學習 Java 過程中,基礎關鍵字往往最容易被忽視卻又最核心。本文深入剖析 super 和 this 的用法、限制及常見誤區,幫助建立準確的心智模型。
super()、super(time)。private 修飾,子類無法通過 super 調用,編譯報錯。因為 private 成員不可繼承,子類不可見。class MyDate extends Date {
private MyDate() { super(); } // OK
private MyDate(long time) { super(time); } // OK
}
// 若 Date 的無參構造器是 private,編譯失敗
super.getTime()。<? super T>super 在泛型中表示類型下界,參數化類型可以是指定類型或其父類型(直到 Object)。
對比:extends 表示上界(子類型)。
// 經典場景:比較兩個對象大小
static <T extends Comparable<? super T>> T min(T a, T b) {
// T 實現了 Comparable,且比較目標可以是 T 或 T 的父類
// 允許傳入 SubTest,即使 Comparable 是由 SuperTest 實現
if (a.compareTo(b) < 0) return a;
return b;
}
class SuperTest implements Comparable<SuperTest> { ... }
class SubTest extends SuperTest { } // SubTest 可直接用於 min()
若寫成 Comparable<? extends T>,則要求 T 本身實現 Comparable,限制了多態性。
this(0)。this(),否則編譯報錯 "Recursive constructor invocation"。this.field = field。this.doSomething()(通常可省略)。許多教材說 "this 代表當前對象,super 代表父類對象",這是不準確的。
instanceof 判斷。public void print() {
System.out.println(this); // 編譯通過,輸出對象地址
System.out.println(this.getClass()); // 編譯通過
System.out.println(super); // 【編譯失敗】super cannot be used outside of a constructor or instance initializer
System.out.println(super.getClass()); // 【編譯失敗】
if (this instanceof MyDate) { ... } // 編譯通過
if (super instanceof Date) { ... } // 【編譯失敗】super cannot be used in instanceof
}
結論:super 無法作為獨立表達式使用,不能賦值給變量,不能參與 instanceof,它只能出現在 super()、super.method()、super.field 這三種上下文中。
| 特性 | this | super |
|---|---|---|
| 本質 | 當前對象引用(變量) | 編譯器指令(關鍵字) |
| 構造器調用 | this() 調用本類其他構造器 | super() 調用父類構造器 |
| 方法/字段訪問 | this.method()、this.field | super.method()、super.field |
| 可作為表達式 | 是(可打印、傳參、判斷類型) | 否(編譯報錯) |
| instanceof 判斷 | 支持 | 不支持 |
| 構造器中順序 | 必須首行,與 super() 互斥 | 必須首行,與 this() 互斥 |
理解這一本質區別,能避免許多繼承層級中的困惑,也是掌握 Java 物件模型的關鍵一步。