class A 
{
        public static final A a=null;
        static{System.out.println("A");}

public class Test

        public static void main(String[] args)  
        {
                Object o=A.a;
        }  
}  我觉得应该什么都不输出,但运行结果输出A。
我想知道,A.a能否在编译期确定值??我认为能确定!
高手说说自己的意见

解决方案 »

  1.   

    class A 
    {
            public static final A a=null;
            static{System.out.println("A");}

    public class Test

            public static void main(String[] args)  
            {
                    //这行混淆了你的概念,去掉这行再试试Object o=A.a;
            }  
    }  
    //结果还是输出"A",也就是说根本不用生成A或者说没进入main之前就已经执行了静态块了。
      

  2.   

    public static final A a=null; //这行也能混淆你,A a,不开辟类空间也不执行类构造函数,
    只有A a=new A();才真正产生这个类。
      

  3.   

    你要知道,类加载->类连接->类初始化这三步,类初始化并非一定会执行的!
    例如,下面的输出就不行执行初始化操作class A 
    {
            public static final int i=1;
            static{System.out.println("A");}

    public class Test

            public static void main(String[] args)  
            {
                    int i=A.i;
            }  
    }  
      

  4.   

    如果final变量是个宏常量呢??编译期可以确定的话就不会被初始化
      

  5.   

    怎么可能运行,你都没有使用类A,JVM不可能加载A.class的
      

  6.   

    debug了一下,i不为final时会加载A,加上final不会加载A
      

  7.   

    那叫编译期常量,就是编译的时候就能确定值的常量。假如A.a的值是编译期常量,如果B类中使用了A.a,编译的是时候在B.class存的就不是A.a的符号引用,而直接是A.a的值,这就不是主动使用
      

  8.   

    程序运行时机:
    类加载-->静态代码块运行-->静态变量初始化-->对应的构造函数运行--->
      

  9.   

    是啊,我现在问的就是A.a能否在编译期确定值?如果能,就不是主动调用也就不会初始化。
    但程序运行结果明显执行了静态初始化。
    也就是说public static final A a=null;不是静态常量,不能在编译期确定,但我觉得应该是编译期常量。
    对A.a的引用应该直接换成null,既然不是主动调用也就不会初始化,自然不应该输出任何东西。
      

  10.   

    这很好办,javap -c Test一下看看取A.a用的什么指令
      

  11.   


    public static void main(java.lang.String[]);
      Code:
       0:   getstatic       #2; //Field A.a:LA;
       3:   astore_1
       4:   return
    使用的是getstatic,符合前面帖子中主动使用情形的第三条
      

  12.   

    getstatic
    我想问的是为什么A.a不是编译期常量,难道因为它是null吗??
      

  13.   

    不单单是null的问题,但null确实是问题之一更重要的一个问题是会写到B.class常量池中的类型是有限的:String和几个基本类型而A.a的类型是A如果将a的类型改为String,为null仍然会去getstatic如果a的类型为String,且有一个字符串值,那么B就使用ldc指令直接从B的常量池中取值,这表示a的值在编译的时候已经放到B.class中了
      

  14.   

    当然,这也并不是说所有String和几个基本类型的常量就会放到B的常量池中去比如a是int类型,其值为32767,使用的就是sipush  32767,表示操作数直接跟在操作码后面如果值为32768,还是会从常量池用ldc指令取值但,不管如何,这种值都放到了B.class中,要么在B的常量池中,要么跟在字节码后面作为参数
      

  15.   

    好吧,就认为null不是编译期常量算了。
    结贴,谢了
    PS:不知道是我网速原因还是CSDN的问题,新的回复老是加载不上来,每次总是有好几楼显示不了,真心耽误时间。
      

  16.   

    class A 
    {
            //public static final int i=1;
           // public static final A a=null;
           public static int i=1; 
           static{System.out.println("A");}

    public class Test

            public static void main(String[] args)  
            {
                    int i=A.i;
                  //Object o=A.a;
            }  
      

  17.   

    class FinalTest1{    public static final int a = 5;    static{
            System.out.println("static code block");
        }
    }public class FinalTest {    public static void main(String[] args) {
            int a = FinalTest1.a;
        }
    }
    static没有被执行,类没有被初始化,因为a是编译时的常量。
    class FinalTest1{    public static final int a = new Integer(5);    static{
            System.out.println("static code block");
        }
    }public class FinalTest {    public static void main(String[] args) {
            int a = FinalTest1.a;
        }
    }
    执行了static,类被初始化,因为a是非编译时的常量。
      

  18.   

    这个程序main方法中使用了A.a,所以执行的时候到这句话的时候,就会先去加载A这个类
    ,加载的过程中类的初始化,会先给静态变量赋值,并且要执行那些静态代码块,所以
    出现了打印AJNI中就会用到这个方式来加载一些东西。
      

  19.   

    static{System.out.println("A");
    静态块,肯定会输入,在类加载是就会输出了,
    静态块只运行一次,这也是静态块的优点。
      

  20.   

    具体来说是这样的,在运行“Object o=A.a;”语句之前,系统会自动加载这个类(注意并非生成该类对象,也并不开辟堆空间。) 加载类的时候,会先加载静态变量,然后加载静态块,运行静态块内的语句。
      

  21.   

    好吧、我来说说java对象实例化步骤吧!
     1 在创建类之前,java虚拟机会检查类是否加载,如果没有加载,就加载这个类,类加载之前,会先加载所有父类(如果有父类的话);
    2 、在堆中非配对象空间,递归分配所有父类和子类的属性空间,注意是属性,属性默认初始化;
    3、进行行属性赋值
    4、检查父类子类是否有静态代码块,如果有,则先执行父类、然后子类静态代码块;
    5、然后递归调用父类构造器(默认调用父类的无参构造器),调用本类构造器;
     静态代码块只执行一次;
          static final 修饰的属性,一旦赋值不能修改,也就是只能初始化,不能被修改
      

  22.   

    getstatic
    我想问的是为什么A.a不是编译期常量,难道因为它是null吗??高手,五体投地,太深奥了