記憶體分析:super 與 this
- 一、繪制記憶體結構圖
- 二、類加載
- 三、對象執行個體化
- 四、調用對象方法
根據以下父子類的定義調用代碼,分析super與this關鍵字在記憶體中的執行過程
class Fu {
int num = 10;
public void method() {} // 父類方法
}
class Zi extends Fu {
int num = 20;
public void method() {} // 子類重寫父類方法
public void show() {
int num = 30;
System.out.println(num); // 30
System.out.println(this.num); // 20
System.out.println(super.num); // 10
}
}
public class Demo {
public static void main(String[] args) {
Zi zi = new Zi();
zi.show();
zi.method();
}
}
一、繪制記憶體結構圖
二、類加載
Fu類、Zi類、Demo類的位元組碼依次被加載到方法區。不同的是,子類在加載過程中會有一個 [[super_class]] 标記,這個标記指向父類,表示子類繼承自父類
三、對象執行個體化
棧中開辟main方法棧幀,内部開辟名為zi的Zi類型變量,堆中執行個體化一個Zi類對象,由于Zi類是繼承自Fu類的,執行個體化的Zi類對象内部會包含一個完整的Fu類對象,Fu類内容與Zi類内容之間互相隔離。JVM使用this指針指向子類内容,使用super指針指向父類内容。最後,将Zi類對象的位址指派給棧空間的zi變量
四、調用對象方法
Zi類中的show()方法棧幀壓棧,并在棧幀中定義一個num變量,進而依次執行:
- 列印方法本身棧幀中局部變量,根據this指針找到自身的成員變量并列印,
- 根據super指針找到Fu類的成員變量并列印。
- 最後,show()方法執行完畢,彈棧。
- 在Zi類的成員方法中找到Zi類的 method() 方法在方法區内的位址,将Zi類 method() 方法壓棧
- 執行Zi類method方法時,内部有一個 super.method() 語句,根據super指針找到父類,在父類的成員方法中找到Fu類的method()方法在方法區中的位址,将Fu類method方法壓棧
- Fu類method方法執行完畢後彈棧,回到Zi類method方法繼續執行完畢後彈棧,
- 程式最後回到main方法繼續執行完畢後彈棧,程式執行結束
圖檔内容源自B站黑馬Java基礎公開課