首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> 更多程式語言 >> 程式設計綜合問答

Java 繼承陷阱:構造方法調用被覆寫方法導致字段未初始化輸出 0

     編輯:程式設計綜合問答

代碼

class Fu {
    int num = 30;
    Fu() { show(); }
    public void show() { System.out.println(num); }
}
class Zi extends Fu {
    int num = 20;
    public void show() { System.out.println(num); }
}
public class Demo {
    public static void main(String[] args) { new Zi(); } // 輸出 0
}

輸出 0 的完整過程

  1. new Zi() 調用子類構造器。
  2. 子類構造器**隱式調用** super()(父類無參構造器)。
  3. 父類構造器執行 show()。
  4. 因多態,**調用的是子類覆寫的 show()**。
  5. 子類 show() 打印 this.num(即 Zi.num)。
  6. 此時 Zi.num **尚未賦值**(子類字段初始化在 super() 之後),默認值 0。
  7. 父類構造器結束,回到子類構造器,執行 Zi.num = 20(字段初始化)。
  8. 主方法結束,若再調用 show() 則輸出 20。

初始化順序鐵律

1. 父類靜態字段/靜態塊
2. 子類靜態字段/靜態塊
3. 父類實例字段/實例塊
4. 父類構造器
5. 子類實例字段/實例塊
6. 子類構造器

最佳實踐

  • 構造器中不要調用可覆寫方法(私有/最終/靜態方法安全)。
  • 若需初始化邏輯,提取到單獨 init() 方法,構造器最後調用,或由外部調用者顯式調用。
  • 使用 @SuppressWarnings("OverridableMethodCallInConstructor") 僅在明確知情時壓制警告。

**這是 Java 初始化順序與多態交互的經典陷阱,必須刻入肌肉記憶。**

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved