Eclipse 和 println 似乎不同意动态设置的私有最终静态字段的价值
Eclipse and println seem to disagree on value of dynamically-set private final static field
在自省的过程中,我发现了一个有趣的情况:
- Eclipse 的调试器工具提示显示
true
- println 打印
false
(注意控制台选项卡中的输出):
我正在尝试设置 private final static
字段的值,我想我做错了吗?
这里到底发生了什么?
import java.lang.reflect.*;
public class Main {
private final static boolean VAR = false; // I want to dynamically set this to true
public static void main(String[] args) throws Exception {
Field field = Main.class.getDeclaredField("VAR");
field.setAccessible(true);
Field modifiersField = Field.class.getDeclaredField("modifiers");
modifiersField.setAccessible(true);
modifiersField.setInt(field, field.getModifiers() & ~Modifier.FINAL);
field.set(null, true);
System.out.println(VAR);
}
}
编译器是'inlining'的static final
值。如果您查看 println
的字节码,您会看到类似于:
iconst_0
invokevirtual java.io.PrintStream.println(boolean)
因为它知道该值不会更改,所以编译器已生成直接加载值 0(表示 false)的代码,而不引用 VAR
变量,因此您对该变量的更改将被忽略。
由于内联,您不能依赖于能够通过反射更改 static final
变量的值。
在自省的过程中,我发现了一个有趣的情况:
- Eclipse 的调试器工具提示显示
true
- println 打印
false
(注意控制台选项卡中的输出):
我正在尝试设置 private final static
字段的值,我想我做错了吗?
这里到底发生了什么?
import java.lang.reflect.*;
public class Main {
private final static boolean VAR = false; // I want to dynamically set this to true
public static void main(String[] args) throws Exception {
Field field = Main.class.getDeclaredField("VAR");
field.setAccessible(true);
Field modifiersField = Field.class.getDeclaredField("modifiers");
modifiersField.setAccessible(true);
modifiersField.setInt(field, field.getModifiers() & ~Modifier.FINAL);
field.set(null, true);
System.out.println(VAR);
}
}
编译器是'inlining'的static final
值。如果您查看 println
的字节码,您会看到类似于:
iconst_0
invokevirtual java.io.PrintStream.println(boolean)
因为它知道该值不会更改,所以编译器已生成直接加载值 0(表示 false)的代码,而不引用 VAR
变量,因此您对该变量的更改将被忽略。
由于内联,您不能依赖于能够通过反射更改 static final
变量的值。