深入理解java类的初始化过程

时间:2022-12-27 15:14:39

一、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类中,我们可以发现首先调用的是父类中带参数的构造器,然后执行的普通初始化块,说明普通初始块是构造器的一种增强版,在编译时普通构造器中的内容被加入到构造器中,在调用父类构造器后执行。