【问题标题】:Eclipse and println seem to disagree on value of dynamically-set private final static fieldEclipse 和 println 似乎不同意动态设置的私有最终静态字段的值
【发布时间】:2017-02-28 22:29:37
【问题描述】:

在玩自省时,我发现了一个有趣的情况:

  • 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);
    }
}

【问题讨论】:

  • 因为 VAR 是一个常量,它可以被内联。

标签: java eclipse static final introspection


【解决方案1】:

编译器正在“内联”static final 值。如果您查看 println 的字节码,您会看到类似:

iconst_0
invokevirtual java.io.PrintStream.println(boolean) 

因为它知道值不会改变编译器生成的代码直接加载值 0(表示 false)而不引用 VAR 变量,因此您对变量的更改将被忽略。

由于内联,您不能依赖通过反射来更改 static final 变量的值。

【讨论】:

    猜你喜欢
    • 2012-09-29
    • 1970-01-01
    • 2014-10-13
    • 2011-03-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-04-20
    相关资源
    最近更新 更多