不創建獨立父類對象。子類實例化時,JVM 在堆中分配單一連續內存區域,包含父類字段與子類字段,僅執行一次 new 指令。
// 反編譯子類構造器
0: aload_0
1: invokespecial #1 // Method Parent."":()V // 調用父構造器
4: aload_0
5: ... // 初始化子類字段
new 指令創建父類實例invokespecial 僅調用父類 <init> 方法初始化繼承字段super 關鍵字本質是訪問當前對象內存中父類字段偏移量區域[對象頭: 12/16 bytes] // Mark Word + Klass Pointer
[父類實例字段] // 按照對齊規則排列
[子類實例字段] // 緊隨其後
[對齊填充] // 8字節對齊
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)]
this 指針 + 父類字段偏移量super.method() 靜態綁定至父類方法表入口Object obj = new Child(); // 編譯類型 Object,運行類型 Child
// 強制轉型 (Parent)obj 僅改變編譯時類型檢查,運行時對象不變
| 誤區 | 事實 |
|---|---|
| 調用 super() 等於 new Parent() | 僅初始化父類字段,無新對象分配 |
| 父類構造器拋異常會創建半個對象 | JVM 回滾分配,對象不存在 |
| 子類對象包含父類對象 | 包含父類字段數據,非對象實例 |