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

Java this 關鍵字深度解析:實例引用、多態行為與成員變數遮蔽機制

     編輯:程式設計綜合問答

核心結論先行

  • this 是當前物件的引用,型別為執行時期的實際類別(而非宣告所在類別)。
  • this 可參與 instanceof、作為參數傳遞、呼叫方法/存取欄位。
  • super 不是引用,無法獨立使用,僅用於呼叫父類建構子或存取被遮蔽的父類成員。
  • 成員變數不支援多態(不會被覆寫),只有方法支援多態。

程式碼逐行執行流程追蹤

public static void main(String[] args) {
    new SubT3().func();  // 關鍵:建立 SubT3 實例,呼叫繼承自 SuperT3 的 func()
    SuperT3 s = new SuperT3();
    System.out.println(s instanceof SubT3); // false:s 是 SuperT3 實例,非 SubT3
}

進入 SuperT3.func() 時的 this 狀態

protected void func() {
    System.out.println(this.name);        // 輸出 "Jack"
    System.out.println(this instanceof SuperT3); // true
    System.out.println(this instanceof SubT3);   // true!關鍵點
}
  1. this 型別是 SubT3:雖然程式碼寫在 SuperT3,但執行時 this 指向的是 new SubT3() 建立的實例。
  2. this.name 輸出 "Jack" 原因:name 是成員變數,不參與多態。編譯器根據引用型別(此處 this 在 SuperT3 方法中,靜態型別為 SuperT3)解析為 SuperT3.name。
  3. this instanceof SubT3 為 true:instanceof 檢查執行時期實際物件型別,物件確實是 SubT3 實例。

記憶體佈局視覺化

SubT3 實例記憶體佈局:
+------------------+
| SuperT3 部分     |  <-- this (SuperT3 型別視圖)
| name = "Jack"    |      |
+------------------+      |
| SubT3 部分       |      +-- this (SubT3 型別視圖,同一起始位址)
| name = "Peter"   |      |
+------------------+

單一物件包含父類與子類的所有實例欄位。父類欄位 name 與子類欄位 name 共存,位於不同偏移量。

為什麼成員變數不支援多態?

設計哲學:若子類同名欄位能覆蓋父類欄位,父類方法存取 this.field 時將看到子類值,導致父類邏輯錯亂(如父類陣列存 0,1,2 卻被子類同名陣列 3,4,5 取代)。

解決方案:

  • 欄位設為 private,提供 getter/setter 方法(方法可多態)。
  • 子類若需不同行為,覆寫方法 而非遮蔽欄位。

super 關鍵字的正確用法

用法範例說明
呼叫父類建構子super(id, name);必須在子類建構子第一行
存取被遮蔽的父類欄位super.name繞過子類同名欄位,直接存取父類欄位
呼叫被覆寫的父類方法super.func()明確調用父類實現,常用於擴充而非完全取代

super 不能:單獨賦值給變數、傳遞給方法、參與 instanceof。

常見誤區釐清

誤區 1:this 型別是宣告所在類別

錯。this 型別是實際物件的類別。父類方法中 this.getClass() == SubT3.class。

誤區 2:this.name 會依據實際物件型別動態派發

錯。欄位存取在編譯期根據引用靜態型別解析。((SuperT3)sub).name 和 ((SubT3)sub).name 可分別存取父/子類同名欄位。

正確認知:多態只適用於實例方法

方法呼叫 this.method() 會動態派發到實際類別的實現。欄位存取、靜態方法、私有方法、建構子均不參與多態。

最佳實踐總結

  1. 欄位私有化:private + getter/setter,避免遮蔽混淆。
  2. 善用 @Override:編譯器驗證確實覆寫父類方法。
  3. 理解靜態/動態型別:引用變數有宣告型別(靜態),物件有實際型別(動態)。
  4. 除錯時檢視 this.getClass():確認執行時期真實型別。

總結

this 是指向當前執行物件的引用,型別為實際類別。成員變數不支援多態,編譯期根據引用靜態型別綁定。super 不是引用,僅用於存取父類被遮蔽/覆寫成員。掌握靜態型別 vs 動態型別、欄位 vs 方法、編譯期綁定 vs 執行期派發三組核心對比,即可徹底理解 Java 物件模型運作機制。

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