首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> Java 程式設計 >> Java 相關知識

淺析 Java 繼承機制:子類實例化時是否創建父類對象?

     編輯:Java 相關知識

核心結論

不創建獨立父類對象。子類實例化時,JVM 在堆中分配單一連續內存區域,包含父類字段與子類字段,僅執行一次 new 指令。

字節碼證據

// 反編譯子類構造器
0: aload_0
1: invokespecial #1  // Method Parent."":()V  // 調用父構造器
4: aload_0
5: ...                // 初始化子類字段
  • 無 new 指令創建父類實例
  • invokespecial 僅調用父類 <init> 方法初始化繼承字段
  • super 關鍵字本質是訪問當前對象內存中父類字段偏移量區域

HotSpot 對象內存佈局

[對象頭: 12/16 bytes]  // Mark Word + Klass Pointer
[父類實例字段]         // 按照對齊規則排列
[子類實例字段]         // 緊隨其後
[對齊填充]             // 8字節對齊

佈局規則(JVM 規範)

  1. 字段按類型分組排序:long/double → int/float → short/char → byte/boolean → reference
  2. 父類字段優先,子類字段後置,不混合
  3. 父類末字段與子類首字段間隙 < 4 bytes 時補齊至 4 bytes
  4. 子類首字段為 long/double 且父類未滿 8 bytes 時,插入 int/short/byte/reference 填充

實例驗證

class Parent { short s; int age; }
class Child extends Parent { String name; int age; float price; }

// 內存佈局圖解
// [Header][Parent.s(2)][padding(2)][Parent.age(4)][Child.name(ref)][Child.age(4)][Child.price(4)][padding(4)]

super 的真實含義

  • 非對象引用,無法單獨傳遞、存儲
  • 編譯器解析為:當前 this 指針 + 父類字段偏移量
  • super.method() 靜態綁定至父類方法表入口

靜態類型 vs 動態類型

Object obj = new Child(); // 編譯類型 Object,運行類型 Child
// 強制轉型 (Parent)obj 僅改變編譯時類型檢查,運行時對象不變

常見誤區澄清

誤區事實
調用 super() 等於 new Parent()僅初始化父類字段,無新對象分配
父類構造器拋異常會創建半個對象JVM 回滾分配,對象不存在
子類對象包含父類對象包含父類字段數據,非對象實例

實戰啟示

  • 繼承本質是字段聚合與方法表繼承,非對象嵌套
  • 組合優於繼承:避免脆弱基類問題,內存佈局更可控
  • final 類無法繼承,編譯器可優化內存佈局(無虛表指針開銷)
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved