Java 關鍵字是語言語義的基石。本文聚焦 final、static、abstract、this、super 五大高頻關鍵字,系統梳理修飾目標、語義規則、常見誤區、字節碼視角與最佳實踐,附完整代碼示例。
| 修飾目標 | 語義 | 關鍵規則 |
|---|---|---|
| 類別 | 不可被繼承 | final class A {} → 無法 class B extends A;典型:String, Integer |
| 方法 | 不可被覆寫 | final void m() {};私有方法隱式 final;構造器不可 final |
| 欄位 (例項/靜態) | 常量,賦值後不可變 | 編譯期常量 (基本型別/String + final + 字面值) 進入常量池,被引用處內聯 |
| 區域變數 | 單次賦值 | 聲明時或後續唯一賦值;匿名內部類/Lambda 捕獲變數隱式要求 final 或 effectively final |
| 參數 | 方法體內不可重賦值 | 僅影響方法體內參考,不影響呼叫端實參 |
final class → ACC_FINAL 類別標誌,JVM 驗證器禁止繼承。final field → ACC_FINAL 欄位標誌,putfield 只能在 <init>/<clinit> 出現。ConstantValue 屬性,使用處直接 ldc 載入,無運行期讀取。static final int MAX_SIZE = 100; 全大寫底線。| 修飾目標 | 語義 | 關鍵規則 |
|---|---|---|
| 欄位 | 靜態欄位,全類共享一份 | 存儲於方法區;ClassName.field 訪問;this.field 合法但不推薦 |
| 方法 | 靜態方法,無 this | 不可訪問非靜態成員;不可覆寫 (可隱藏);ClassName.method() 調用 |
| 代碼塊 | 靜態初始化塊 | 類加載時按順序執行一次;用於複雜靜態欄位初始化 |
| 內部類 | 靜態內部類 | 無外部類例項引用;可獨立創建 new Outer.Inner();單例模式首選載體 |
| 導入 | 靜態導入 | import static java.lang.Math.PI; 直接用 PI |
父類 static 欄位/塊 → 子類 static 欄位/塊 →
父類 instance 欄位/塊 → 父類構造器 →
子類 instance 欄位/塊 → 子類構造器
final |
| 方法 | 抽象方法,無方法體 | 僅聲明;子類必須實現 (除非子類也 abstract);不可 private/static/final/synchronized/native |
this.name = name;this(...) 必須為構造器**第一條語句**。other.doSomething(this);、return this; (Builder/鏈式)。super(...) 必須為子類構造器**第一條語句**;無參 super() 可省略 (編譯器自動插入)。super.field、super.method()。super.overriddenMethod() (模板方法模式常見)。super.super.method() 編譯錯誤;只能訪問直接父類。
class Father {
String v = "Father";
Father() { System.out.println("Father()"); }
Father(String v) { this.v = v; System.out.println("Father(String)"); }
void show() { System.out.println("Father.show: " + v); }
}
class Son extends Father {
String v = "Son"; // 遮蔽父類欄位
Son() {
super(); // 顯式調用父類無參構造器
System.out.println("Son()");
}
Son(String v) {
super(v); // 調用父類帶參構造器
this.v = v + "_son"; // this 訪問子類欄位
System.out.println("Son(String)");
}
@Override void show() {
System.out.println("Son.show: this.v=" + this.v + ", super.v=" + super.v);
super.show(); // 調用父類被覆寫方法
}
void test() {
String v = "Local"; // 區域變數遮蔽
System.out.println("Local: " + v);
System.out.println("this.v: " + this.v);
System.out.println("super.v: " + super.v);
}
}
public class Main {
public static void main(String[] args) {
Son s = new Son("Test");
s.show();
s.test();
}
}
Father()
Son()
Son.show: this.v=Son, super.v=Father
Father.show: Father
Local: Local
this.v: Son
super.v: Father
final | 不可變/不可繼承/不可覆寫 | 類、方法、欄位、區域變數、參數 | 常量、不可變類、模板方法鎖定 |
| static | 屬於類、共享、無 this | 欄位、方法、代碼塊、內部類、導入 | 工具方法、單例、常量、計數器 |
| abstract | 契約、延遲實現 | 類、方法 | 框架骨架、強制子類實現 |
| this | 當前例項引用 | 僅非靜態方法/構造器內 | 區分同名、構造器鏈、鏈式 API |
| super | 父類例項引用 | 僅非靜態方法/構造器內 | 調用父構造器、訪問被遮蔽成員、模板方法 |
final 方法不可被覆寫,但 **可被重載**。static 方法 **不可覆寫**,子類同名靜態方法為 **隱藏**。abstract 方法 **不可 private**,否則子類不可見無法實現。this/super **不可用於靜態上下文**。this(...) 與 super(...) **二擇一,且必須首行**。內化這五大關鍵字的語義邊界,即能寫出語義精確、結構清晰、演進安全的 Java 代碼。