Java 類別初始化遵循嚴格順序,理解順序對避免邏輯錯誤至關重要。以下程式碼演示關鍵點:
class Cup {
Cup(int marker) { System.out.println("Cup(" + marker + ")"); }
void f(int marker) { System.out.println("f(" + marker + ")"); }
}
class Cups {
static Cup c1 = new Cup(1);
Cup c3 = new Cup(3);
static Cup c2 = new Cup(2);
Cups() { System.out.println("Cups()"); }
Cup c4 = new Cup(4);
}
public class ExplicitStatic {
Cups c = new Cups();
{ System.out.println("Hello"); } // 實例初始化區塊
public static void main(String[] args) {
System.out.println("Inside main()");
Cups.c1.f(99);
ExplicitStatic x = new ExplicitStatic();
}
static Cups x = new Cups();
}
Cup(1) Cup(2) Cup(3) Cup(4) Cups() Inside main() f(99) Cup(3) Cup(4) Cups() Hello
c2 雖在 c3 後宣告,但因 static 先於實例欄位初始化,故 Cup(2) 輸出早於 Cup(3)。new Cups() 時,靜態欄位 c1、c2 不再初始化,故無 Cup(1)、Cup(2) 輸出。c4 在建構子前宣告,但建構子 Cups() 輸出早於 Cup(4),因欄位初始化實際插入建構子最前端。main 類別執行順序特殊:先靜態初始化,再執行 main,不執行實例初始化區塊與建構子,除非在 main 內明確 new。移除 ExplicitStatic x = new ExplicitStatic(); 後,Cups c = new Cups() 與 Hello 皆不執行。{ ... } 非靜態區塊屬實例初始化區塊,每次建構物件皆執行,順序與欄位初始化同步(按原始碼順序),早於建構子本體。