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”建设. (编辑:台州站长网) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |