我找到了以下代码段:
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的长度,输出长度也会增加
有人可以解释一下吗?
我对反思知之甚少。
答案 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"