2013-05-09 23 views
9

Sadece keşfetmek oldu java yansıma API ve ben Kod Parçacığı aşağıdaki karşılaşılanJava Yansıma Pasaj çıkış

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); 
     } 
    } 

Çıktı: Ben devletler kümesi yönteminin belgelerini okuyun

six times seven 43 
six times seven 43 
42 

o değerini ayarlar olduğunu Verilen nesne için alanın Ancak kodun çıktılarını anlayamıyorum, çünkü tüm durumlarda 42 basmalıdır.

Kodda neler olup bittiğine dair herhangi bir fikir verebilir misiniz?

+1

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

cevap

4
 System.out.println(42); 

println(int) değil println(Object) çağırıyor. Boks asla olmaz. Bu daha hızlı yapar ve 1.5'den önce de çalıştı.

Diğer durumlarda, Integer.valueOf(int) aracılığıyla boks yapıyorsunuz. Bu yöntem, her zaman -128 ve 127 (aynı değerler diğer değerler için aynı davranışı olabilir veya olmayabilir) değerleri için tam olarak aynı Integer nesnelerini döndürüyor olarak tanımlanır. Yani programınızda 42 tane kutunun olduğu yerde aynı nesneyi alacaksınız ve bu nesnede value değerini ayarladığınızda, hangi referanstan geçtiği önemli değil. Eğer koduna açıkça boks koymak için olsaydı

, bu şekilde görünecektir:

 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); 

biz Integer.valueOf( döner 42 için de aynı nesne bildiği gibi, kod etkili bir geçerli:

 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

Kavramak biraz zor. Bana daha fazla ayrıntı bulabileceğim bir referans verebilir misiniz? – ankurtr

+0

@ ankur.trapasiya Bokstan mı? Ayrıntılar, "Integer.valueOf" ve JLS için API dokümanlarında bulunur. –

+0

@ ankur.trapasiya [[Here] (http://stackoverflow.com/questions/3130311/weird-java-boxing)] Boks ve önbelleğe alma Integers hakkında ilginç bir sorunuz var. Ayrıca printf (String formatı, Object ... args) '' format'ında kullanılan argümanlar olarak Object’ler gerektirdiğinden, Java 'auto'' int' '' Integer'' i will§lemini yapar, fakat önbelleğe alınan 'Integer' değerini değiştirdikten sonra 42-43 bu değer basılacaktır. 'println (int)' bu sorunu yaşamadığından, boks gerektirmez. Ayrıca System.out.printf ("altı kez yedi% d% n", yeni Tamsayı (6 * 7)); 'önbelleğe alınmayacak 42 değerine sahip yeni Tamsayı oluşturmak için de deneyebilirsiniz. – Pshemo