一、final:不可變的承諾
| 修飾對象 | 效果 | 典型用例 |
| class | 不可被繼承 | public final class String、final class ImmutableDTO |
| method | 不可被重寫 | 模板方法模式固定骨架、效能優化(內聯) |
| variable (基本型別) | 值不可變更 | final int MAX_SIZE = 100 常數 |
| variable (引用型別) | 引用不可變更 (指向同一物件) | final List<String> list = new ArrayList<>() 仍可 list.add() |
| 參數 | 方法體內不可重新賦值 | 防止誤賦值、匿名內部類捕獲 |
記憶口訣:final = 最後/不可更改。編譯期常數傳播優化、執行期 JIT 內聯優化皆依賴 final 語意。
二、static:屬於類別而非實例
| 修飾對象 | 效果 | 關鍵限制 |
| field (類別變數) | 全域共享單一副本,類別載入時分配記憶體 | 非 static 方法不可直接訪問 instance field |
| method (類別方法) | 無需實例即可呼叫 ClassName.method() | 方法內不可使用 this/super,不可訪問 instance 成員 |
| 初始化區塊 | 類別載入時執行,按出現順序,僅執行一次 | 不可拋受檢例外,僅能初始化 static field |
| 內部類別 | 不持有外部類別實例引用 | 外部類別不可為 static |
| 導入 | import static pkg.Class.MEMBER 靜態導入 | — |
記憶體模型:static field 存放於方法區(Java 8 以前 PermGen,Java 8+ Metaspace),instance field 存放於堆積物件內。
三、super:父類別引用
| 用法 | 語法 | 規則 |
| 呼叫父類別建構子 | super(arg1, arg2...) | 必須是子類別建構子第一行;若父類別無無參建構子,子類別必須顯式呼叫 |
| 呼叫父類別方法 | super.method(args) | 通常用於重寫方法中擴展父邏輯 |
| 存取父類別欄位 | super.field | 解決子父同名欄位遮蔽問題 |
四、this:當前實例引用
| 用法 | 語法 | 規則 |
| 呼叫本類別其他建構子 | this(arg1, arg2...) | 必須是建構子第一行;不可與 super() 共存 |
| 呼叫本類別方法 | this.method() | 可省略 this.,但加上更明確 |
| 存取本類別欄位 | this.field | 解決參數/區域變數遮蔽欄位 |
| 傳遞當前實例 | other.register(this) | 回調、建構者模式常見 |
五、建構子中 this() vs super() 核心規則
- 兩者互斥,必須二選一置於第一行。
- 若兩者皆無,編譯器隱式插入
super()(呼叫父類別無參建構子)。
this() 形成建構子鏈,最終必須以 super() 結束。
六、靜態方法陷阱
public class Trap {
static void staticMethod() {
// this.x = 1; // 編譯錯誤:static 方法無 this
// super.method(); // 編譯錯誤:static 方法無 super
}
}
static 方法屬於類別,不屬於任何實例,故無 this/super 語境。
七、總結對照表
| 關鍵字 | 核心語意 | 作用範圍 | 常見誤區 |
| final | 定值/封印 | 類別、方法、欄位、參數、區域變數 | final 引用 ≠ 物件不可變 |
| static | 類別級共享 | 欄位、方法、初始化區塊、內部類別、導入 | static 方法不可存取 instance 成員 |
| super | 父類別委派 | 建構子、方法、欄位存取 | super() 必須在建構子第一行 |
| this | 當前實例自指 | 建構子、方法、欄位、傳遞實例 | this() 與 super() 不可共存 |