欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

常量的编译 博客分类: PUZZLE  

程序员文章站 2024-02-20 21:20:52
...
public class PrintWords {
    public static void main(String[] args) {
        System.out.println(Words.FIRST  + " " + 
                           Words.SECOND + " " +
                           Words.THIRD);
    }
}

public class Words {
    private Words() { };  // Uninstantiable

    public static final String FIRST  = "the";
    public static final String SECOND = null;
    public static final String THIRD  = "set";
} 

现在假设你像下面这样改变了那个库类并且重编译了这个类,但并不重编译客户端的程序:
public class Words {
    private Words() { };  // Uninstantiable

    public static final String FIRST  = "physics";
    public static final String SECOND = "chemistry";
    public static final String THIRD  = "biology";
}

此时,客户端的程序会打印出什么呢?

一个常量变量的定义是:一个在编译期被常量表达式初始化的final的原始类型或String类型的变量[JLS 4.12.4]。在知道了这些知识之后,我们有理由认为客户端程序会将初始值Words.FIRST, Words.SECOND, Words.THIRD编译进class文件,然后无论Words类是否被改变,客户端都会打印the null set。
运行了程序,你会发现它打印的是the chemistry set。
关键是null不是一个编译期常量表达式