本題考察 Java 類初始化過程中靜態變數、實例變數、建構子、實例初始化塊的執行順序,以及前向引用導致的讀取預設值陷阱。理解初始化時間線是解題關鍵。
package Mar2017;
public class Ques0301 {
private int a = getB(); // 實例變數初始化表達式
private int b = 1; // 實例變數初始化
private int getB() { return b; }
public static void main(String[] args) {
System.out.println((new Ques0301()).a);
}
}
new Ques0301() 執行流程:
1. 分配記憶體,所有欄位設為預設值:a=0, b=0
2. 執行實例初始化(按宣告順序):
a. 第 1 行:a = getB() → 調用 getB()
- getB() 返回 b
- 此時 b 尚未執行初始化表達式,仍為預設值 0
- 所以 a = 0
b. 第 2 行:b = 1 → b 變為 1(但 a 已固定為 0)
3. 執行建構子主體(隱式無參建構子,無額外代碼)
4. 物件建立完成,main 印出 a = 0
輸出結果:0
// 方案 1:調整宣告順序
private int b = 1;
private int a = getB(); // 現在 getB() 讀到 b=1
// 方案 2:在建構子中初始化
private int a; private int b;
public Ques0301() { b = 1; a = getB(); }
// 方案 3:getB() 直接返回常數或計算值,不依賴欄位
private int a = 1; // 或 private int a = computeA();
class Test {
static int x = getY();
static int y = 2;
static int getY() { return y; }
public static void main(String[] args) { System.out.println(x); }
}
// 輸出? 0(同理:靜態初始化按順序,x 初始化時 y 尚為 0)
類初始化順序是 Java 基礎中極易掉坑的考點。鐵律:**靜態→實例(按宣告順序)→建構子**。任何在初始化表達式中調用方法讀取同類欄位,必須確認該欄位已完成初始化,否則讀到預設值導致邏輯錯誤。