结论:对于静态变量、静态初始化块、变量、初始化块、构造器,它们的初始化顺序依次是(静态变量、静态初始化块)>(变量、初始化块)>构造器。
1 public class Test4 { 2 @Test 3 public void test(){ 4 child child = new child(); 5 } 6 } 7 8 class parent{ 9 public static String parentStaticField = "父类静态变量"; 10 public String parentNormalField ="父类普通变量"; 11 static { 12 System.out.println(parentStaticField); 13 System.out.println("父类静态块"); 14 } 15 16 { 17 System.out.println(parentNormalField); 18 System.out.println("父类普通块"); 19 } 20 21 public parent(){ 22 23 System.out.println("父类构造方法"); 24 } 25 } 26 27 class child extends parent{ 28 public static String childStaticField = "子类静态变量"; 29 public String childNormalField ="子类普通变量"; 30 static { 31 System.out.println(childStaticField); 32 System.out.println("子类静态块"); 33 } 34 35 { 36 System.out.println(childNormalField); 37 System.out.println("子类普通块"); 38 } 39 40 public child(){ 41 System.out.println("子类构造方法"); 42 } 43 }
输出:
1 父类静态变量 2 父类静态块 3 子类静态变量 4 子类静态块 5 父类普通变量 6 父类普通块 7 父类构造方法 8 子类普通变量 9 子类普通块 10 子类构造方法
执行过程:
1、当执行到new child时,装载器寻找已经编译的child类的代码(也就是child.class文件)。在装载的过程中,装载器注意到它有一个基类,于是它再装载基类。不管你创不创建基类对象,这个过程总会发生。如果基类还有基类,那么第二个基类也会被装载,依此类推。
2、执行根基类的static初始化,然后是下一个派生类的static初始化,依此类推。这个顺序非常重要,因为派生类的“static初始化”有可能要依赖基类成员的正确初始化。
3、当所有必要的类都已经装载结束,创建child类对象。
4、child类存在父类,则调用父类的构造函数,可以使用super来指定调用哪个构造函数。
基类的构造过程以及构造顺序,同派生类的相同。首先基类中各个变量按照字面顺序进行初始化,然后执行基类的构造函数的其余部分。
5、对子类成员数据按照它们声明的顺序初始化,执行子类构造函数的其余部分。