一个有意思的盲区:
执行psvm的时候,类的构造函数并不会执行,也就是说这时候类的实例并不存在。
public static void main(String[] args) {} 复制代码
C extens B,B extends A , Main类中 new C()
public class InitLearn { static class A{ static Print pA1 =new Print("static pA1"); static { System.out.println("Static Initialization Block A"); } static Print pA2 =new Print("static pA2"); { System.out.println("Initialization Block A Before Construct"); } public A(){ System.out.println("Construct A"); } { System.out.println("Initialization Block A After Construct"); } }; static class B extends A{ static Print pB1 =new Print("static pB1"); static Print pB2 =new Print("static pB2"); static { System.out.println("Static Initialization Block B"); } { System.out.println("Initialization Block B Before Construct"); } public B(){ System.out.println("Construct B"); } { System.out.println("Initialization Block B After Construct"); } }; static class C extends B{ static Print pC1 =new Print("static pC1"); static { System.out.println("Static Initialization Block C"); } static Print pC2 =new Print("static pC2"); { System.out.println("Initialization Block C Before Construct"); } public C(){ System.out.println("Construct C"); } { System.out.println("Initialization Block C After Construct"); } }; static class Print{ public Print(String v){ System.out.println(v); } } static { System.out.println("static{} of the class run psvm to test"); } public static void main(String[] args) { new C(); //new C(); } } 复制代码
输出:
static{} of the class run psvm to test //测试类的静态初始化块,在调用psvm前 static pA1 //A类静态成员 定义在静态初始化块前 Static Initialization Block A //A类静态初始化块 static pA2 //A类静态成员 定义在静态初始化块后 static pB1 //B类静态成员 定义在静态初始化块前 static pB2 //B类静态成员 定义在静态初始化块前 Static Initialization Block B //B类静态初始化块 static pC1 //C类静态成员 定义在静态初始化块前 Static Initialization Block C //C类静态初始化块 static pC2 //C类静态成员 定义在静态初始化块后 Initialization Block A Before Construct //A类初始化块 Initialization Block A After Construct //A类初始化块 Construct A //A类构造方法 Initialization Block B Before Construct Initialization Block B After Construct Construct B Initialization Block C Before Construct Initialization Block C After Construct Construct C 复制代码
InitLearn类是肯定没有被实例化过的,但是由于执行main入口函数用到了InitLearn类,于是static初始化块也被执行了;
所有的静态初始化块都优先执行,其次才是非静态的初始化块和构造函数,它们的执行顺序是:
如果之后再new 一个B(),只会出现以下日志,静态的初始化过程只执行一次
Initialization Block A Before Construct Initialization Block A After Construct Construct A Initialization Block B Before Construct Initialization Block B After Construct Construct B Initialization Block C Before Construct Initialization Block C After Construct Construct C 复制代码