我正在探索java反射API,我遇到了以下代码片段
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);
}
}
输出:six times seven 43
six times seven 43
42
我阅读了set方法的文档,其中声明它为给定对象设置字段的值。但是我不能理解代码的输出,因为它应该在所有情况下打印42。
谁能告诉我代码中发生了什么?
System.out.println(42);
呼叫println(int)
,而不是println(Object)
。拳击从来没有发生过。这使得它更快,并且在1.5之前也可以工作。
在其他情况下,您正在拳击通过Integer.valueOf(int)
。这个方法被定义为总是为-128和127之间的值返回完全相同的Integer
对象(对于其他值可能有也可能没有相同的行为)。因此,无论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);