Java编译期常量

来源:互联网 发布:淘宝开店品类 编辑:程序博客网 时间:2024/05/21 19:36


public class Const{    public static void main(String args[]){     //System.out.println(Data.i1); //System.out.println(Data.i2);//initialization! //System.out.println(Data.b1);//initialization! //System.out.println(Data.s1); //System.out.println(Data.i3);//initialization! //System.out.println(Data.a); //initialization!  //System.out.println(Data.e); //initialization! }}class Data{  static{      System.out.println("initialization!");  }  public static final int i1=0;  public static final Integer i2=0;  public static final Boolean b1=true;  public static final String s1="0";  public static final int i3=s1.length();  public static final A a=new A();  public static final Enum e=E.A;}class A{}enum E {    A,B,C,D,E,F,G;}



class PrintWords {      publicstaticvoid main(String[] args) {             System.out//引用常量变量                           .println(Words.FIRST + " "                                         + Words.SECOND + " "                                         + Words.THIRD);      }}class Words {      // 常量变量      publicstaticfinal String FIRST = "the";      // 非常量变量      publicstaticfinal String SECOND = null;      // 常量变量      publicstaticfinal String THIRD = "set";}

现在假设你像下面这样改变了那个库类并且重新编译了这个类,但并不重新编译客户端的程序PrintWords

class Words {

      publicstaticfinal String FIRST = "physics";

      publicstaticfinal String SECOND = "chemistry";

      publicstaticfinal String THIRD = "biology";

}

此时,端的程序会打印出什么呢?结果是 the chemistry set,不是the null set,也不是physics chemistry biology,为什么?原因就是 null 不是一个编译期常量表达式,而其他两个都是。

对于常量变量(如上面Words类中的FIRSTTHIRD)的引用(如在PrintWords类中对Words.FIRSTWords.THIRD的引用)会在编译期被转换为它们所表示的常量的值(即PrintWords类中的Words.FIRSTWords.THIRD引用会替换成"the""set")。

一个常量变量(如上面Words类中的FIRSTTHIRD)的定义是,一个在编译期被常量表达式(即编译期常量表达式)初始化的final的原生类型或String类型的变量。

那什么是“编译期常量表达式”?精确定义在[JLS 15.28]中可以找到,这样要说的是null不是一个编译期常量表达式。

由于常量变量会编译进客户端,API的设计者在设计一个常量域之前应该仔细考虑一下是否应该定义成常量变量。

如果你使用了一个非常量的表达式去初始化一个域,甚至是一个final或,那么这个域就不是一个常量。下面你可以通过将一个常量表达式传给一个方法使用得它变成一个非常量:

class Words {

      // 以下都成非常量变量

      publicstaticfinal String FIRST = ident("the");

      publicstaticfinal String SECOND = ident(null);

      publicstaticfinal String THIRD = ident("set");

      privatestatic String ident(String s) {

             return s;

      }

}

总之,常量变量将会被编译进那些引用它们的类中。一个常量变量就是任何常量表达式初始化的原生类型或字符串变量。且null不是一个常量表达式。



0 0