Java 在运行时未反映常量值

Java 在运行时未反映常量值,java,compiler-construction,constants,Java,Compiler Construction,Constants,假设编译以下两个类。第一种是代表客户;第二,图书馆类 public class Test{ public static void main(String[] args) { System.out.println(Lib.FIRST + " " + Lib.SECOND + " " + Lib.THIRD); } } public class Lib{

假设编译以下两个类。第一种是代表客户;第二,图书馆类

public class Test{
    public static void main(String[] args) {
        System.out.println(Lib.FIRST + " " +
                           Lib.SECOND + " " +
                           Lib.THIRD);
    }
}


public class Lib{
    private Lib() { }; // Uninstantiable
    public static final String FIRST = "the";
    public static final String SECOND = null;
    public static final String THIRD = "set";
}
印刷品:

{空集}

现在假设您按如下方式修改库类并重新编译它,但不编译客户端程序:

public class Lib{
    private Lib() { }; // Uninstantiable
    public static final String FIRST = "physics";
    public static final String SECOND = "chemistry";
    public static final String THIRD = "biology";
}
印刷品:

{化学集}


为什么
第二个
值发生了更改,而
第一个
第三个
值没有发生更改?

编译时,编译器将内联值(即“the”和“set”),而
null
则没有内联值。为了避免类似的情况,您可以使用访问器方法。

这是一个已知的警告-在编译客户端程序时,常量是内联的,因此您还必须重新编译它

另请参见:


类路径中有两个“Lib”类吗?你重启虚拟机了吗?你的容器是什么?这是直接从盒子里拿出来的。相同的字符串常量和所有内容。如果你想了解更前沿的Java案例,这本书是一本很棒的读物。这个问题确实是逐字抄袭自Java拼图游戏(拼图93)。(+1)好奇。。。我不知道。这是公认的答案,但回答不够微妙。具体来说,null不是常量表达式,因此它不是内联的,而其他两个值是用常量表达式定义的,因此它们的值是内联的(这就是为什么“化学集”最终被打印出来的原因)。不鼓励在静态字段上使用访问器方法吗?这是一个例外情况吗?我只是说如果他想避免重新编译客户机类本身。不,我完全理解你的意图,我不是说你说错了什么,不要误解我。只是想看看您是否意识到在这种情况下使用accessor会出现异常。