Java 物件創建時,父類與子類的靜態塊、構造塊、構造器執行順序是經典面試必考點。本文透過一道具體選擇題,逐步演示完整初始化流程,建立清晰的心智模型。
class X {
Y b = new Y(); // ① 成員變量初始化
X() { System.out.print("X"); } // ② 構造器
}
class Y {
Y() { System.out.print("Y"); } // ③ 構造器
}
public class Z extends X {
Y y = new Y(); // ④ 成員變量初始化
Z() { System.out.print("Z"); } // ⑤ 構造器
public static void main(String[] args) { new Z(); }
}
// 輸出選項: A) Z B) YZ C) XYZ D) YXYZ
| 步驟 | 動作 | 輸出 | 說明 |
|---|---|---|---|
| 1 | 加載類 `X`、`Y`、`Z` (無靜態成員/塊,無輸出) | - | 類加載階段 |
| 2 | 調用 `Z()` 構造器 → 隱式 `super()` → 調用 `X()` | - | 構造器鏈啟動 |
| 3 | 執行 `X` 的非靜態成員初始化:`Y b = new Y()` | Y | ① 號位置,調用 `Y()` 構造器 |
| 4 | 執行 `X()` 構造器體:`System.out.print("X")` | X | ② 號位置 |
| 5 | 返回 `Z()`,執行 `Z` 的非靜態成員初始化:`Y y = new Y()` | Y | ④ 號位置,再次調用 `Y()` |
| 6 | 執行 `Z()` 構造器體:`System.out.print("Z")` | Z | ⑤ 號位置 |
最終輸出:`YXYZ` (選項 D)
class X { Y b = new Y(); X() { System.out.print("X"); } }
class Y { Y() { System.out.print("Y"); } }
public class Z extends X { Y y = new Y(); Z() { System.out.print("Z"); }
public static void main(String[] args) { new Z(); } }
// 控制台輸出: YXYZ
**口訣:靜態父→靜態子→父成員→父構造→子成員→子構造。** 牢記「成員初始化先於本類構造器,父類鏈優於子類」的核心原則,任何複雜繼承鏈初始化順序題皆可迎刃而解。