以下是示例程序:
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()返回更新值?
解决方法
I am wondering,how can i make getM() return updated value?
在决赛中,你不能.返回“旧”值是合法的行为,如JLS 17.5.3:
Even then,there are a number of complications. If a final field is
initialized to a constant expression (§15.28) in the field
declaration,changes to the final field may not be observed,since
uses of that final field are replaced at compile time with the value
of the constant expression.Another problem is that the specification allows aggressive
optimization of final fields. Within a thread,it is permissible to
reorder reads of a final field with those modifications of a final
field that do not take place in the constructor.
请参阅该章中包含的指导性示例.
克服这一规定的尝试必须包括将优化器与堆栈混合在一起,并且是最脆弱的.如果您选择修改字段,那么根据定义,这些字段不应该是final.如果你想要这个性能方面的原因(你,是真的吗?),然后JSR 292提供的机制做“almost final”建设.