输出结果如下 为什么?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;
}
}
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 有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");
}
}
实例化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代码。
我知道
Animal() {
System.out.println(this + " constructor");
}
这个构造函数要在静态初始化块之后执行,但是这句 {
System.out.println(this + " initializer");
}
属于什么? 为什么它会在静态初始化块之前执行了??
public static Animal Cat=new Animal(),Dog=new Animal();这句话很重要。”初始化块“ 这个初始化块,是不是包含除了 构造函数和静态代码块以外的所有语句?
static {
System.out.println("static initializer");
}
不知道理解的是否正确?
1、先执行静态代码,然后是初始化代码,然后是构造函数。(后面两个只在对象实例化时才执行,而静态代码是在类引用是就执行,而且只执行一次)
2、所谓初始化代码,应该是说除了静态代码,变量定义,函数定义(包括构造函数)以外的语句。这部分代码,其实也可以放在构造函数中的。对于你的这个问题,比较关键的理解就是public static Animal Cat=new Animal(),Dog=new Animal(); 这句本身是静态代码,同时又在执行对象实例化,所以看起来(其他)静态代码在后面执行了。
Dog constructor
Cat initializer
Cat constructor
static initializer输出结果里有Cat 和 Dog 初始化结果还有静态代码的初始化结果。 为什么最后初始化代码块和构造函数没再执行一次?因为开始 Cat,Dog;的时候分别只是调用了他们,最后他们本身也应该在静态代码块之后执行一次才对?这样理解错误在哪?
并不是什么构造函数/初始化代码没用。由于使用了类Animal,所以执行其静态代码,按如下顺序:执行静态代码1:实例化静态变量cat(这时会调用初始化代码和构造函数)
执行静态代码2:实例化静态变量dog(这时会调用初始化代码和构造函数)
执行静态代码3:没有进行任何实例化,仅仅是打印出static initializer。