输出结果如下 为什么?Cat initializer
Cat constructor
Dog initializer
Dog constructor
static initializer谁能分析下初始化流程,谢谢。enum Animal {
Cat,Dog;
Animal() {
System.out.println(this + " constructor");
} {
System.out.println(this + " initializer");
}
static {
System.out.println("static initializer");
} public static void main(String... s) {
Animal animal = Animal.Cat;
}
}

解决方案 »

  1.   

    Animal 是enum的,所以类装载后,必须先把内部有哪些东西先创建好,这个在类的初始化阶段进行
    1 有Cat, cat 本身当然是Animal的了,然后调用了类的代码块
        {
            System.out.println(this + " initializer");
        }
    然后调用了构造函数
     System.out.println(this + " constructor");
    2 同样初始化 Dog4 调用了Animal的static 初始化代码完毕我们看一下编译生成的代码就更清楚了
    import java.io.PrintStream;final class Animal extends Enum
    {    public static final Animal Cat;
        public static final Animal Dog;
        private static final Animal ENUM$VALUES[];    private Animal(String s, int i)
        {
            super(s, i);
            System.out.println((new StringBuilder()).append(this).append(" initializer1").toString());
            System.out.println((new StringBuilder()).append(this).append(" initializer2").toString());
            System.out.println((new StringBuilder()).append(this).append(" constructor").toString());
        }    public static transient void main(String args[])
        {
        }    public static Animal[] values()
        {
            Animal aanimal[];
            int i;
            Animal aanimal1[];
            System.arraycopy(aanimal = ENUM$VALUES, 0, aanimal1 = new Animal[i = aanimal.length], 0, i);
            return aanimal1;
        }    public static Animal valueOf(String s)
        {
            return (Animal)Enum.valueOf(test/Animal, s);
        }    static 
        {
            Cat = new Animal("Cat", 0);
            Dog = new Animal("Dog", 1);
            ENUM$VALUES = (new Animal[] {
                Cat, Dog
            });
            System.out.println("static initializer");
        }
    }
      

  2.   

    Cat,Dog都相当于static类型的静态属性,所有禁态代码执行只按出现的先后顺序。所以先实例化cat对象,然后实例化dog对象,最后才执行最后的static代码。
    实例化Cat对象时,首先执行了初始化块,然后才执行构造函数。如果写成类的形式,大致如下:class Animal {
        public static Animal Cat=new Animal(),Dog=new Animal();
        Animal() {
            System.out.println(this + " constructor");
        }    {
            System.out.println(this + " initializer");
        }
        static {
            System.out.println("static initializer");
        }    public static void main(String... s) {
            Animal animal = Animal.Cat;
        }
    }
    这样就可以很明显看出,这里有两部分static代码。
      

  3.   

    有个疑问。
    我知道
    Animal() {
    System.out.println(this + " constructor");
    }
     这个构造函数要在静态初始化块之后执行,但是这句    {
            System.out.println(this + " initializer");
        }
    属于什么? 为什么它会在静态初始化块之前执行了??
      

  4.   

    那是类的普通初始化块,实在初始化静态对象cat,dog时执行出来的。
      

  5.   

    谢谢2楼和3楼的朋友,
    public static Animal Cat=new Animal(),Dog=new Animal();这句话很重要。”初始化块“ 这个初始化块,是不是包含除了 构造函数和静态代码块以外的所有语句?
      

  6.   

    ”那是类的普通初始化块,实在初始化静态对象cat,dog时执行出来的。“按你这里的话理解下:1,开始先是初始化了 Animal Cat = new Animal();  在这里显示调用了代码块System.out.println(this   +   "   initializer"); , 然后调用了构造函数 Animal(),2, 初始化 Animal Dog = new Animal();  同样调用代码块和构造函数3, 调用静态代码块
        static {
                System.out.println("static initializer");
               }
    不知道理解的是否正确?
      

  7.   

    这个执行顺序自然是正确的,但是,你应该明白两点:
    1、先执行静态代码,然后是初始化代码,然后是构造函数。(后面两个只在对象实例化时才执行,而静态代码是在类引用是就执行,而且只执行一次)
    2、所谓初始化代码,应该是说除了静态代码,变量定义,函数定义(包括构造函数)以外的语句。这部分代码,其实也可以放在构造函数中的。对于你的这个问题,比较关键的理解就是public   static   Animal   Cat=new   Animal(),Dog=new   Animal(); 这句本身是静态代码,同时又在执行对象实例化,所以看起来(其他)静态代码在后面执行了。
      

  8.   

    恩。。 基本上明白了。还有个问题: Dog initializer
    Dog constructor
    Cat initializer
    Cat constructor
    static initializer输出结果里有Cat 和 Dog 初始化结果还有静态代码的初始化结果。 为什么最后初始化代码块和构造函数没再执行一次?因为开始 Cat,Dog;的时候分别只是调用了他们,最后他们本身也应该在静态代码块之后执行一次才对?这样理解错误在哪?
      

  9.   

    最后没有实例化任何对象,自然就不需要再执行一次。
    并不是什么构造函数/初始化代码没用。由于使用了类Animal,所以执行其静态代码,按如下顺序:执行静态代码1:实例化静态变量cat(这时会调用初始化代码和构造函数)
    执行静态代码2:实例化静态变量dog(这时会调用初始化代码和构造函数)
    执行静态代码3:没有进行任何实例化,仅仅是打印出static initializer。
      

  10.   

    完全清楚了,谢谢microsealkey !