Java初始化
总结:初始化顺序:父类静态变量——> 父类静态代码块 ——>子类静态变量 ——> 子类静态代码块 ——>父类非静态变量 ——>父类构造代码块——> 父类构造函数 ——>字类非静态变量 ——>子类构造代码块——> 子类构造函数
静态代码块只会被执行一次!!!!
1. 关键:Java一个类的成员变量初始化先于构造函数执行。详细请参考:
参考博客:传送门
2. 该代码为何输出:YXYZ
class X{
Y y=new Y();
public X(){
System.out.print("X");
}
}
class Y{
public Y(){
System.out.print("Y");
}
}
public class Z extends X{
Y y=new Y();
public Z(){
System.out.print("Z");
}
public static void main(String[] args) {
new Z();
}
}
3.原因
执行顺序如下列注释序号所示
//下面代码输出YXYZ的原因,和Java调用机制有关
class X{
//5.初始化动作总是先于构造函数执行,所以先执行类的初始化动作
//6.此处会调用类Y的构造函数
Y y=new Y();
public X(){
//3.此处隐藏了super()语句,所以调用直接父类Object的构造函数
//4.Object没有父类,所以程序返回到此处.
//10.本类初始化完成,执行权回到此处,打印输出X,程序返回
System.out.print("X");
}
}
class Y{
public Y(){
//7.此处隐藏了super()语句,所以调用直接父类Object的构造函数
//8.Object没有父类,所以程序返回到此处.
//9.没有成员变量需要初始化,所以继续执行下面代码,打印输出Y,程序返回
//13.此处隐藏了super()语句,所以调用直接父类Object的构造函数
//14.Object没有父类,所以程序返回到此处.
//15.没有成员变量需要初始化,所以继续执行下面代码,打印输出Y,程序返回
System.out.print("Y");
}
}
public class Z extends X{
//12.程序来到此处执行初始化动作,此处会调用类Y的构造函数
Y y=new Y();
public Z(){
//2.此处隐藏了super()语句,所以调用直接父类X的构造函数
//11.执行权回到此处,但本类成员变量尚未初始化,先初始化
//16.本类初始化完成,执行权回到此处,打印输出Z,程序返回
System.out.print("Z");
}
public static void main(String[] args) {
//1.调用类Z的构造函数
new Z();
//17.程序执行到此处,结束。
}
}