匿名內部類是 Java 中一種特殊的內部類寫法,它沒有類名,直接在創建物件時「現寫現用」。常用於:
new 介面或父類別() {
// 實現抽象方法或覆寫父類方法
@Override
public void method() {
// 具體邏輯
}
};
以下範例展示如何透過匿名類別動態注入「列印」與「進食」行為:
package com.example.anonymous;
/**
* 定義行為契約
*/
interface Action {
void print();
void eat();
}
/**
* 匿名類別示範類
*/
public class AnonymousClassDemo {
/**
* 執行器:接受行為介面,執行預定流程
*/
public static String execute(Action action) {
System.err.println("=== 開始執行核心流程 ===");
action.print();
action.eat();
return "execute() 回傳值";
}
/**
* 測試方法:以匿名類別實現 Action 介面並傳入
*/
public String testExecute() {
// 此處 new Action() {...} 即為匿名內部類
return execute(new Action() {
@Override
public void print() {
System.out.println("匿名類別:正在列印文件...");
}
@Override
public void eat() {
System.out.println("匿名類別:享用美味午餐...");
}
});
}
public static void main(String[] args) {
AnonymousClassDemo demo = new AnonymousClassDemo();
System.out.println(demo.testExecute());
}
}
=== 開始執行核心流程 ===
匿名類別:正在列印文件...
匿名類別:享用美味午餐...
execute() 回傳值
| 特性 | 說明 |
|---|---|
| 隱式繼承/實現 | 自動實現介面所有抽象方法,或繼承父類非 final 方法 |
| 存取外部變數 | 可存取外部方法的 final 或「實際上 final」的區域變數(Java 8+ 不需顯式宣告 final) |
| 無建構子 | 無類名,故無法定義建構子;可用實例初始化區塊 { } 替代 |
| 類別檔案命名 | 編譯後產生 外部類$1.class、外部類$2.class 等 |
Java 8 引入 Lambda 表達式,對於函數式介面(單一抽象方法),可大幅簡化程式碼:
// 僅適用於單一方法介面
execute(() -> System.out.println("Lambda 列印"));
注意:本範例的 Action 介面有兩個方法,無法使用 Lambda,此時匿名類別仍是必要選擇。
匿名內部類是 Java 實現「行為參數化」的經典工具,雖然 Lambda 表達式在單方法場景下取代了它,但在多方法介面、需要存取外部狀態、或需覆寫多個方法的情況下,匿名類別依然不可或缺。掌握其語法與適用邊界,能讓你的程式碼更靈活、更具表達力。