JVM 載入類需經歷三大步驟:
類初始化 → 子類建構子 → 父類建構子 → 實例成員變數初始化 → 繼續執行子類建構子語句
static field(靜態欄位賦值)。static initializer(靜態區塊)。public class Demo {
private static String str = "initialization static field"; // static field initializer
static { System.out.println("This is static initializer"); } // static initializer
}
僅初始化介面中定義的常數(static final 欄位),不會 初始化父介面。
Object),但實現的介面不會初始化。static final 編譯期常數(基本型別或 String)被引用時,不會觸發 定義它的類初始化。public class Initialization {
static { System.out.println("Initialization Main class"); }
public static void main(String[] args) {
System.out.println(Sub.y); // 2005
System.out.println(Sub.x); // 觸發 Super 初始化
System.out.println(Sub.z); // 觸發 Sub 初始化
}
}
class Super { public static int x = 2006; static { System.out.println("Initialization Super"); } }
class Sub extends Super { public static final int y = 2005; public static int z; static { System.out.println("Initialization Sub"); } }
輸出:
Initialization Main class 2005 Initialization Super 2006 Initialization Sub 0
解析:Sub.y 為編譯期常數,不觸發初始化;Sub.x 定義於 Super,觸發父類初始化;Sub.z 非常數,觸發 Sub 初始化;static 變數有預設值(z=0)。
this() 呼叫本類其他建構子,遞歸執行步驟 2-6。super() 呼叫父類建構子,遞歸執行步驟 2-6。instance initializer 與 instance variable initializer(第二次初始化)。public class InitializationOrder { public static void main(String[] args) { new SubClass(); } }
class SuperClass { static { System.out.println("SuperClass static"); } SuperClass(String str) { System.out.println(str); } }
interface Interface { static SuperClass su = new SuperClass("Interface new SuperClass"); }
class SubClass extends SuperClass implements Interface {
static { System.out.println("SubClass static"); }
private SuperClass su = new SuperClass("initialization variable");
SubClass() { super("super"); new SuperClass("new SuperClass"); }
}
輸出:
SuperClass static SubClass static super initialization variable new SuperClass
解析:介面 Interface 的 static 欄位不會 在實現類初始化時執行,只有直接使用介面時才會初始化。
掌握 類初始化(static 階段) 與 物件建立(實例階段) 的精確順序,特別是父子類交織、介面靜態欄位、編譯期常數等細節,是編寫正確、可預測 Java 程式的關鍵基礎。