天天看點

Java - 記憶體分析:super 與 this一、繪制記憶體結構圖二、類加載三、對象執行個體化四、調用對象方法

記憶體分析: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();
	}
}
           

一、繪制記憶體結構圖

Java - 記憶體分析:super 與 this一、繪制記憶體結構圖二、類加載三、對象執行個體化四、調用對象方法

二、類加載

Fu類、Zi類、Demo類的位元組碼依次被加載到方法區。不同的是,子類在加載過程中會有一個 [[super_class]] 标記,這個标記指向父類,表示子類繼承自父類

Java - 記憶體分析:super 與 this一、繪制記憶體結構圖二、類加載三、對象執行個體化四、調用對象方法

三、對象執行個體化

棧中開辟main方法棧幀,内部開辟名為zi的Zi類型變量,堆中執行個體化一個Zi類對象,由于Zi類是繼承自Fu類的,執行個體化的Zi類對象内部會包含一個完整的Fu類對象,Fu類内容與Zi類内容之間互相隔離。JVM使用this指針指向子類内容,使用super指針指向父類内容。最後,将Zi類對象的位址指派給棧空間的zi變量

Java - 記憶體分析:super 與 this一、繪制記憶體結構圖二、類加載三、對象執行個體化四、調用對象方法

四、調用對象方法

Zi類中的show()方法棧幀壓棧,并在棧幀中定義一個num變量,進而依次執行:

  1. 列印方法本身棧幀中局部變量,根據this指針找到自身的成員變量并列印,
  2. 根據super指針找到Fu類的成員變量并列印。
  3. 最後,show()方法執行完畢,彈棧。
    Java - 記憶體分析:super 與 this一、繪制記憶體結構圖二、類加載三、對象執行個體化四、調用對象方法
  1. 在Zi類的成員方法中找到Zi類的 method() 方法在方法區内的位址,将Zi類 method() 方法壓棧
  2. 執行Zi類method方法時,内部有一個 super.method() 語句,根據super指針找到父類,在父類的成員方法中找到Fu類的method()方法在方法區中的位址,将Fu類method方法壓棧
  3. Fu類method方法執行完畢後彈棧,回到Zi類method方法繼續執行完畢後彈棧,
  1. 程式最後回到main方法繼續執行完畢後彈棧,程式執行結束
Java - 記憶體分析:super 與 this一、繪制記憶體結構圖二、類加載三、對象執行個體化四、調用對象方法

圖檔内容源自B站黑馬Java基礎公開課