例子里每部分開(kāi)頭的數(shù)字,由大到小代表實(shí)際執(zhí)行順序仑荐。
/**
* 控制臺(tái)打印
*/
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();
}
}
實(shí)驗(yàn)輸出結(jié)果:
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
結(jié)果證明:
對(duì)象在class文件加載完畢粘招,以及為各成員在方法區(qū)開(kāi)辟好內(nèi)存空間之后,就開(kāi)始所謂“初始化”的步驟:
- 基類靜態(tài)代碼塊洒扎,基類靜態(tài)成員字段 (并列優(yōu)先級(jí),按代碼中出現(xiàn)先后順序執(zhí)行)
- 派生類靜態(tài)代碼塊栈戳,派生類靜態(tài)成員字段 (并列優(yōu)先級(jí),按代碼中出現(xiàn)先后順序執(zhí)行)
- 基類普通代碼塊子檀,基類普通成員字段 (并列優(yōu)先級(jí),按代碼中出現(xiàn)先后順序執(zhí)行)
- 基類構(gòu)造函數(shù)
- 派生類普通代碼塊褂痰,派生類普通成員字段 (并列優(yōu)先級(jí),按代碼中出現(xiàn)先后順序執(zhí)行)
- 派生類構(gòu)造函數(shù)