java类初始化顺序

Posted 我不吃饼干呀

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了java类初始化顺序相关的知识,希望对你有一定的参考价值。

http://www.cnblogs.com/wenruo/articles/5349525.html

先不考虑父类。

当创建类对象时,先初始化静态变量和静态块,然后是非静态变量和非静态代码块,然后是构造器。由于静态成员只会被初始化一次,所以如果静态成员已经被初始化过,将不会被再次初始化。

例如

 1 class A {
 2     A(int maker) {
 3         System.out.println("A(" + maker + ")");
 4     }
 5 }
 6 
 7 class Test {
 8     static A a1 = new A(1);
 9     A a2 = new A(2);
10     {
11         System.out.println("非静态的代码块"); 
12     }
13     A a3 = new A(3);
14     static {
15         System.out.println("静态块");
16         A a4 = new A(4);
17     }
18     static void f() {System.out.println("f()");}
19     Test() {
20         System.out.println("Test()");
21     }
22     static A a5 = new A(5);
23 }
24 
25 public class Initialize {
26     public static void main(String[] args) {
27         new Test();
28         System.out.println();
29         new Test();
30     }
31 }

输出为:

A(1)
静态块
A(4)
A(5)
A(2)
非静态的代码块
A(3)
Test()

A(2)
非静态的代码块
A(3)
Test()

 

对于静态成员,不仅是初始化对象时才会初始化,当第一次引用静态变量或者静态函数时都会使静态成员初始化。

还是上面的代码,小改一下:

 1 class A {
 2     A(int maker) {
 3         System.out.println("A(" + maker + ")");
 4     }
 5 }
 6 
 7 class Test {
 8     static A a1 = new A(1);
 9     A a2 = new A(2);
10     {
11         System.out.println("非静态的代码块"); 
12     }
13     A a3 = new A(3);
14     static {
15         System.out.println("静态块");
16         A a4 = new A(4);
17     }
18     static void f() {System.out.println("f()");}
19     Test() {
20         System.out.println("Test()");
21     }
22     static A a5 = new A(5);
23 }
24 
25 public class Initialize {
26     public static void main(String[] args) {
27         Test.f();
28         System.out.println();
29         new Test();
30     }
31 }

这次将输出:

A(1)
静态块
A(4)
A(5)
f()

A(2)
非静态的代码块
A(3)
Test()

 

然后考虑下父类。

当子类的静态域被初始化时候,那一定要先初始化父类的静态域。

当创建子类对象时,要先初始化静态域(如果之前未初始化),先是父类然后子类。之后初始化父类的非静态域和父类构造器,然后是子类。

例(新手起名废求破):

 1 class XD {
 2     XD(int maker) {
 3         System.out.println("XD(" + maker +")");
 4     }
 5 }
 6 
 7 class Father {
 8     Father() {
 9         System.out.println("Father()");
10     }
11     static XD xd = new XD(1);
12     XD xd1 = new XD(2);
13 }
14 
15 class Son extends Father {
16     Son() {
17         System.out.println("Son()");
18     }
19     static XD xd = new XD(3);
20     XD xd1 = new XD(4);
21     static void f() { System.out.println("f()"); }
22 }
23 
24 
25 public class InitializeWithExtends {
26     public static void main(String[] args) {
27         new Son();
28         System.out.println();
29         new Son();
30     }
31 }

输出

XD(1)
XD(3)
XD(2)
Father()
XD(4)
Son()

XD(2)
Father()
XD(4)
Son()

 

以上是关于java类初始化顺序的主要内容,如果未能解决你的问题,请参考以下文章

java类加载顺序

Java 的类加载顺序

java类加载机制&初始化顺序

一文详解:Java中父子类静态块构造块构造方法成员变量之间的初始化先后顺序与执行先后顺序

Java对象实例化顺序

Java类成员初始化顺序