还有就是编译时常量的一些性质,哪位大侠能给说一下?

解决方案 »

  1.   

    static final int a=5;据说在翻译成的字节码里面是看不到a这个符号的,而是直接的写入5这个值。
    那么:如果我定义:static final int b=a+1; 那么b算不算?
    还有,static final int c= "hello world".length()这个算不算?
      

  2.   

    怎么净答非所问呢?我给一个例子吧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";
    }现在编译以后,输出结果是很明确的。
    那么,当我把Words.java修改成以下形式:public class Words {
        private Words() { };  // Uninstantiabl
        public static final String FIRST  = "physics";
        public static final String SECOND = "chemistry";
        public static final String THIRD  = "biology";
    }重新编译Words.java,但是不编译PrintWords.java,直接运行PrintWords,输出结果会是什么呢?
      

  3.   


    结果肯定是不会变的啊,因为你没有改变PrintWords.class里面的内容
      

  4.   

    对于final类型的静态变量,如果在编译时就能计算出变量的取值,那么这种变量被看做编译时常量。例如:
    class Temp{
    private static final int a=10;
    //编译期可以计算出来a=10,所以a是编译期常量
    private static final int b=((int)(Math.random()*10));
    //编译期不可以计算出b的值,所以b不是编译期常量
    }
      

  5.   


    b算,c不算。将PrintWords 编译后的class文件反编译成Java文件如下:System.out.println((new StringBuilder("the ")).append(Words.SECOND).append(" ").append("set").toString());从中可以发现Words.FIRST  和Words.THIRD已经用常量代替了
      

  6.   

        楼主可以用类的初始化机制来试验,就拿我上面的例子来说吧!在说之前我不知道你对类的初始化机制了解多少,这里我稍微给你提点:在JAVA中,只有对类的首次主动使用时才会初始化类(你可以把static代码块是否被执行看成是类是否被初始化的标志,当然,这样说法并不一定准确,但这里我们可以先用这个方法来测试),对类中的编译期常量进行访问时是不会导致类的初始化的(这里我们就是利用这个原理)。修改后的例子如下:public class MyJava{
    public static void main(String[] args){
    System.out.println(Temp.a); //A处
    System.out.println(Temp.b); //B处
    }
    }class Temp{
    static{
    System.out.println("Temp类已被初始化");
    }
    public static final int a=10;
      //编译期可以计算出来a=10,所以a是编译期常量
      public static final int b=((int)(Math.random()*10));
      //编译期不可以计算出b的值,所以b不是编译期常量
    }
    当我们把B处的输出语句注释掉后,打印结果是:10     这说明类没被初始化(说明a是编译期常量)
    当我们把A处的输出语句注释掉后,把B处的语句复原,打印的结果是:
    Temp类已被初始化
    4(这是JAVA虚拟机自动生成的随机数)
    这说明类被初始化(说明b不是编译期常量)
      

  7.   

    lh_fengyuzhe 可否告知是用什么软件反编译的?
      

  8.   

    用chenchengamao说的方法测试:public class Const{
      public static void main(String args[]){
          System.out.println(Test.b);
          System.out.println(Test.c);
      }
    }
    class Test{
       static final int a=1; 
       static final int b=a+1; 
       static final int c= "hello world".length();
       static{
          System.out.println("初始化类!");
       }
    }果然,访问b不会导致Test的初始化,访问C会。但是,难道在编译时,C的值无法计算出来吗?
      

  9.   

    javac并不是一个优化的编译器,像涉及到方法调用的,需要运行的时候去确定结果,基本不会进行优化。
    java的大部分优化是由jvm进行的,那才是真正的深度编译优化。
      

  10.   


    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;
    }结论:
    编译时常量只有可能是基本类型和String类型,而不可能是任何的引用类型,包括枚举,包装。