2013-05-09 6 views
9

私はJavaのリフレクションAPIを模索していたと私は、次のコードスニペットJavaのリフレクションスニペ​​ット出力

public class Main { 
    public static void main(String[] args) throws IllegalAccessException, NoSuchFieldException{ 
      Field value=Integer.class.getDeclaredField("value"); 
      value.setAccessible(true); 
      value.set(42, 43); 

      System.out.printf("six times seven %d%n",6*7); 
      System.out.printf("six times seven %d%n",42); 
      System.out.println(42); 
     } 
    } 

出力が発生しました:私はそれが値を設定することを述べているsetメソッドのドキュメントを読んで

six times seven 43 
six times seven 43 
42 

を指定されたオブジェクトのフィールドのしかし、私はコードの出力を理解することができないので、すべてのケースで42を出力する必要があります。

誰でもコード内で何が起こっているのかを把握できますか?

+1

http://www.dzone.com/snippets/reflection-integer-destroyer –

答えて

4
 System.out.println(42); 

ないprintln(Object)println(int)を呼んでいます。ボクシングは決して起こらない。それは速くなり、1.5より前にも働いた。

その他の場合、あなたはInteger.valueOf(int)でボクシングしています。このメソッドは、-128と127の間の値のオブジェクトを常に同じように返すものとして定義されています(他の値でも同じ動作をする場合とそうでない場合があります)。したがって、あなたのプログラムでは42がボックス化されていて、同じオブジェクトが得られます。このオブジェクトにvalueという値を設定すると、どの参照を読み込んでいても変更されます。

あなたがコードに明示的にボクシングに入れていた場合、それは次のようになります。

 value.set(Integer.valueOf(42), 43); 

     System.out.printf("six times seven %d%n",Integer.valueOf(6*7)); 
     System.out.printf("six times seven %d%n",Integer.valueOf(42)); 
     System.out.println(42); 

我々はInteger.valueOf(返します42のためのまったく同じオブジェクトを知っているように、コードが効果的である:

 Integer obj42 = Integer.valueOf(42); 

     value.set(Integer.valueOf(obj42, 43); 

     System.out.printf("six times seven %d%n", obj42); 
     System.out.printf("six times seven %d%n", obj42); 
     System.out.println(42); 
+0

把握が難しいです。あなたは私に詳細を見つけることができる参考文献を教えてください。 – ankurtr

+0

@ ankur.trapasiyaボクシングの?詳細は 'Integer.valueOf'とJLSのAPIドキュメントにあります。 –

+0

@ ankur.trapasiya [[Here(http://stackoverflow.com/questions/3130311/weird-java-boxing)]あなたはボクシングとキャッシング整数に関する興味深い質問があります。また 'printf(String format、Object ... args)'はObjectを 'format'で使われる引数として要求します。Javaは' int'を 'Integer'にautoboxしますが、42を表す' Integer'の値を43に変更したので、この値が印刷されます。 'println(int)'はボクシングを必要としないのでこの問題はありません。また、System.out.printf(6回7%d%n "、新しい整数(6 * 7));を試してみてください。キャッシュされない値42の新しい整数を作成する – Pshemo