一个有意思的盲区:html
执行psvm的时候,类的构造函数并不会执行,也就是说这时候类的实例并不存在。java
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初始化块也被执行了;spa
全部的静态初始化块都优先执行,其次才是非静态的初始化块和构造函数,它们的执行顺序是:调试
若是以后再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
复制代码