java – 修改由JIT编译的最终值
|
我注意到一个非常奇怪的事情,在通过反射改变最后一个字段之后,返回该字段的方法一直是旧的值.我想这可能是因为JIT编译器. 以下是示例程序: public class Main
{
private static final Main m = new Main();
public static Main getM()
{
return m;
}
public static void main(String args[]) throws Exception
{
Main m = getM();
int x = 0;
for(int i = 0;i<10000000;i++)
{
if(getM().equals(m))
x ++;
}
Field f = Main.class.getDeclaredField("m");
f.setAccessible(true);
removeFinal(f);
Main main1 = new Main();
f.set(null,main1);
Main main2 = (Main) f.get(null);
Main main3 = getM();
System.out.println(main1.toString());
System.out.println(main2.toString());
System.out.println(main3.toString());
}
private static void removeFinal(Field field) throws NoSuchFieldException,IllegalAccessException
{
Field modifiersField = Field.class.getDeclaredField("modifiers");
modifiersField.setAccessible(true);
modifiersField.setInt(field,field.getModifiers() & ~Modifier.FINAL);
}
}
结果是: Main@1be6f5c3 Main@1be6f5c3 Main@6b884d57 我想知道,我如何使getM()返回更新值? 解决方法
在决赛中,你不能.返回“旧”值是合法的行为,如JLS 17.5.3:
请参阅该章中包含的指导性示例. 克服这一规定的尝试必须包括将优化器与堆栈混合在一起,并且是最脆弱的.如果您选择修改字段,那么根据定义,这些字段不应该是final.如果你想要这个性能方面的原因(你,是真的吗?),然后JSR 292提供的机制做“almost final”建设. (编辑:十堰站长网) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |
