Reflectionで最終フィールドを変更した後、そのフィールドを返すメソッドは常に古い値を返すというのは非常に奇妙なことに気付きました。これは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);
}
}
結果は次のとおりです:ここで
は、サンプルプログラムである、私は疑問に思って
[email protected]
[email protected]
[email protected]
、どのように私はGETM()の戻り値は、更新することができますか?
キーワード 'final'は、コンパイラがインライン化できるようにします。なぜあなたはこれをする必要がありますか? –
JITを強制的に再コンパイルする方法はありますか? – user3009344
JITではなくjavacコンパイラです。 –