初始化块:
静态初始化块;非静态初始化块
执行顺序:
所有的静态初始化块都优先执行,其次才是非静态的初始化块和构造函数,它们的执行顺序是:
1父类的静态初始化块
2子类的静态初始化块
3父类的初始化块
4父类的构造函数
5子类的初始化块
6子类的构造函数
每个类的静态初始化块都只在第一次实例化该类对象时执行一次
说明:
静态初始化块的优先级最高,也就是最先执行,并且仅在类第一次被加载时执行;
非静态初始化块和构造函数后执行,并且在每次生成对象时执行一次;
非静态初始化块的代码会在类构造函数之前执行。因此若要使用,应当养成把初始化块写在构造函数之前的习惯,便于调试;
静态初始化块既可以用于初始化静态成员变量,也可以执行初始化代码;
非静态初始化块可以针对多个重载构造函数进行代码复用
例子
1 class A {
2 static {
3 System.out.println("Static init A.");
4 }
5
6 {
7 System.out.println("Instance init A.");
8 }
9
10 A() {
11 System.out.println("Constructor A.");
12 }
13 }
14
15 class B extends A {
16 static {
17 System.out.println("Static init B.");
18 }
19
20 {
21 System.out.println("Instance init B.");
22 }
23
24 B() {
25 System.out.println("Constructor B.");
26 }
27 }
28
29 class C extends B {
30
31 static {
32 System.out.println("Static init C.");
33 }
34
35 {
36 System.out.println("Instance init C.");
37 }
38
39 C() {
40 System.out.println("Constructor C.");
41 }
42 }
43
44 public class Main {
45
46 static {
47 System.out.println("Static init Main.");
48 }
49
50 {
51 System.out.println("Instance init Main.");
52 }
53
54 public Main() {
55 System.out.println("Constructor Main.");
56 }
57
58 public static void main(String[] args) {
59 C c = new C();
60 B b = new B();
61 }
62 }
结果:
(C c = new C())
Static init Main. --main函数再Main类中调用,先初始化Main类
Static init A. --父父类static块 ((静态初始化块的优先级最高,也就是最先执行,并且仅在类第一次被加载时执行;)
Static init B. --父类static块
Static init C. --子类static块
Instance init A. --父父类非static块
Constructor A. --父父类构造函数
Instance init B. --父类非static块
Constructor B. --父类构造函数
Instance init C. --子类非static块
Constructor C. --子类构造函数
(B b = new B())
Instance init A. --父类非static块 (静态初始化块的优先级最高,也就是最先执行,并且仅在类第一次被加载时执行;非静态初始化块和构造函数后执行,并且在每次生成对象时执行一次;)
Constructor A. --父类构造函数
Instance init B. --子类非static块
Constructor B. --子类构造函数