java – 修改由JIT编译的最终值

前端之家收集整理的这篇文章主要介绍了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()返回更新值?

解决方法

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”建设.

猜你在找的Java相关文章