9

我只是在探索 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。

任何人都可以深入了解代码中发生的事情吗?

4

1 回答 1

4
        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);
于 2013-05-09T17:01:17.267 回答