一、java的初始化过程
在创建一个对象时,通过new关键字调用构造方法时,会不断的调用父类的构造方法。如果在一个类中同时存在静态初始化块、普通初始化块以及构造方法时,类的加载顺序应该是如何呢?
1 class Root { 2 static { 3 System.out.println("Root的静态初始化块!"); 4 } 5 { 6 System.out.println("Root的普通初始化块!"); 7 } 8 public Root() { 9 System.out.println("Root无参构造方法!"); 10 } 11 } 12 13 class Mid extends Root { 14 static { 15 System.out.println("Mid的静态初始化块!"); 16 } 17 { 18 System.out.println("Mid的普通初始化块!"); 19 } 20 public Mid() { 21 System.out.println("Mid无参构造方法!"); 22 } 23 public Mid(String msg) { 24 this(); 25 System.out.println("Mid的带参数构造器,其参数值:" + msg); 26 } 27 } 28 29 class Leaf extends Mid { 30 static { 31 System.out.println("Leaf的静态初始化块!"); 32 } 33 { 34 System.out.println("Leaf的普通初始化块!"); 35 } 36 public Leaf() { 37 super("java疯狂讲义!"); 38 System.out.println("执行Leaf的构造器!"); 39 } 40 } 41 42 public class Test { 43 public static void main(String[] args) { 44 new Leaf(); 45 new Leaf(); 46 } 47 }
执行结果:
Root的静态初始化块!
Mid的静态初始化块!
Leaf的静态初始化块!
Root的普通初始化块!
Root无参构造方法!
Mid的普通初始化块!
Mid无参构造方法!
Mid的带参数构造器,其参数值:java疯狂讲义!
Leaf的普通初始化块!
执行Leaf的构造器!
-----------------
Root的普通初始化块!
Root无参构造方法!
Mid的普通初始化块!
Mid无参构造方法!
Mid的带参数构造器,其参数值:java疯狂讲义!
Leaf的普通初始化块!
执行Leaf的构造器!
从执行结果上来看,所有的静态初始化块都是在类加载时执行了一次,再次new对象时,不会重复执行。普通初始化块会重复执行。
结论:
1.静态初始化中加载的内容属于类本身,在类被加载到内存时执行,在执行后被保存在内存中。
2.从Mid类中,我们可以发现首先调用的是父类中带参数的构造器,然后执行的普通初始化块,说明普通初始块是构造器的一种增强版,在编译时普通构造器中的内容被加入到构造器中,在调用父类构造器后执行。