Java程序初始化顺序
1.按Java理论,父类与子类的初始化顺序为:
1.初始化父类静态变量
2.初始化父类的静态代码块
3.初始化子类的静态变量
4.初始化子类的静态代码块
5.父类的非静态变量
6.父类的非静态代码块
7.父类的构造函数
8.子类的非静态变量
9.子类的非静态代码块
10.子类的构造函数
验证代码:
public class Base { static { System.out.println("Base static block"); } { System.out.println("Base block"); //draw(); } public Base() { System.out.println("Base constructor"); } public void draw() { System.out.println("Base draw"); } }
public class Deived extends Base{ private int radi=1; static { System.out.println("Deived static block"); } { System.out.println("Deived block"); } public Deived(int x) { radi =x; System.out.println("Deived constructor"); //draw(); } public static void main(String args[]) { new Deived(5); } @Override public void draw() { System.out.println("Deived draw "+radi); } }
Base static block Deived static block Base block Base constructor Deived block Deived constructor
这个理论从大的方面看没问题,但有一个疑问:类的方法在什么时候初始化呢?
修改代码如下(取消draw方法注释):
public class Base { static { System.out.println("Base static block"); } { System.out.println("Base block"); draw(); } public Base() { System.out.println("Base constructor"); } public void draw() { System.out.println("Base draw"); } }
public class Deived extends Base{ private int radi=1; static { System.out.println("Deived static block"); } { System.out.println("Deived block"); } public Deived(int x) { radi =x; System.out.println("Deived constructor"); draw(); } public static void main(String args[]) { new Deived(5); } @Override public void draw() { System.out.println("Deived draw "+radi); } }
结果如下:
Base static block Deived static block Base block Deived draw 0 Base constructor Deived block Deived constructor Deived draw 5
根据结果说明,在父类在初始化的时候就能调用子类的draw方法,将调用draw代码放在父类构造函数时结果也一样。说明类的方法初始化与此次字段的初始化顺序没有关系,在这些步骤之前就已经存在该方法了。
所以将经典理论补充完善如下:
父类(子类)方法初始化(先后顺序未知)->
父类静态字段-父类静态方法块->
子类静态字段->子类静态方法块->
父类非静态字段->父类非静态方法块->父类构造函数->
子类非静态字段->子类非静态方法块->子类构造函数。
如有错误,欢迎指出~