例子里每部分开头的数字,由大到小代表实际执行顺序。
/**
* 控制台打印
*/
class Log{
public static String baseFieldInit(){System.out.println("Base Normal Field");return "";}
public static String baseStaticFieldInit(){System.out.println("Base Static Field");return "";}
public static String fieldInit(){System.out.println("Normal Field");return "";}
public static String staticFieldInit(){System.out.println("Static Field");return "";}
}
/**
* 基类
*/
class Base {
/*1*/ static {System.out.println("Base Static Block 1");}
/*1*/ private static String staticValue=Log.baseStaticFieldInit();
/*1*/ static {System.out.println("Base Static Block 2");}
/*3*/ {System.out.println("Base Normal Block 1");}
/*3*/ private String value=Log.baseFieldInit();
/*3*/ {System.out.println("Base Normal Block 2");}
/*4*/ Base(){System.out.println("Base Constructor");}
}
/**
* 派生类
*/
public class Derived extends Base{
/*2*/ static {System.out.println("Static Block 1");}
/*2*/ private static String staticValue=Log.staticFieldInit();
/*2*/ static {System.out.println("Static Block 2");}
/*5*/ {System.out.println("Normal Block 1");}
/*5*/ private String value=Log.fieldInit();
/*5*/ {System.out.println("Normal Block 2");}
/*6*/ TestInit(){System.out.println("Constructor");}
/**
* MAIN 主线程
*/
public static void main(String[] args){
Derived d=new Derived();
}
}
实验输出结果:
Base Static Block 1
Base Static Field
Base Static Block 2
Static Block 1
Static Field
Static Block 2
Base Normal Block 1
Base Normal Field
Base Normal Block 2
Base Constructor
Normal Block 1
Normal Field
Normal Block 2
Constructor
结果证明:
对象在class文件加载完毕,以及为各成员在方法区开辟好内存空间之后,就开始所谓“初始化”的步骤:
- 基类静态代码块,基类静态成员字段 (并列优先级,按代码中出现先后顺序执行)
- 派生类静态代码块,派生类静态成员字段 (并列优先级,按代码中出现先后顺序执行)
- 基类普通代码块,基类普通成员字段 (并列优先级,按代码中出现先后顺序执行)
- 基类构造函数
- 派生类普通代码块,派生类普通成员字段 (并列优先级,按代码中出现先后顺序执行)
- 派生类构造函数