奇怪的Java代码

时间:2013-03-15 12:45:37

标签: java reflection

我找到了以下代码段:

import java.lang.reflect.Field;
public class Test {
    public static void main(String[] args) {
        System.out.println("Inside main");
    }
    static {
        try {
            Field value = String.class.getDeclaredField("value");
            value.setAccessible(true);
            value.set("Inside main", value.get("Inside static bolck"));
        } catch (Exception e) {
            throw new AssertionError(e);
        }
    }
}

根据我的理解,输出应为Inside static bolck,但输出为Inside stat,字符长度为Inside main
*如果我增加Inside main的长度,输出长度也会增加  有人可以解释一下吗? 我对反思知之甚少。

4 个答案:

答案 0 :(得分:4)

在我的JDK上,String还有一个count成员,需要更新以反映新的长度。

还有一个offset字段,可能需要也可能不需要更新(可能不是这种情况)。

最后,有一个hash字段,在您更改value后将不再正确。

由于此代码依赖于String的特定实现的未记录的详细信息,因此它非常脆弱且非常不可移植。例如(帽子提示@assylias),Oracle have removed the count and offset fields in JDK 7u6。如果您要从7u5升级到7u6,那么您的代码会突然表现不同。

答案 1 :(得分:1)

代码假设String类的实际实现,例如该类有一个名为“value”的字段。

由于String类的内部状态不是API或语言规范的一部分,因此实际实现将因不同供应商的VM之间或同一供应商的不同VM版本之间的不同而不同。

答案 2 :(得分:0)

"Inside main"在值[]中包含11个字符(value []是String类中的私有字段)
字符串value[]首先在您定义字符串"Inside main"时初始化。 现在,您正在使用反射更改value[]的值,即String中的私有实例变量,然后它必须只匹配字符串Inside static bolck中的11个字符

答案 3 :(得分:0)

当您改变“Inside main”时,您可以value.get()字符串< =“Inside main”。更改 - “Inside main”到“Inside main(8个空格)”并打印

"Inside static bolck"