概念釐清
| 概念 | 語法 | 本質 | 用途 |
| 匿名物件 | new ClassName() | 具體類別的無名實例 | 一次性使用、不需複用 |
| 匿名內部類別 | new Interface() { ... } 或 new Parent() { ... } | 隱式定義的子類別/實作類別的無名實例 | 即時實作介面/覆寫方法 |
方法參數接收示例
interface Callback { void execute(); }
class Processor { void process(Callback cb) { cb.execute(); } }
// 1. 傳遞匿名內部類別 (實作介面)
processor.process(new Callback() {
@Override public void execute() { System.out.println("匿名類別"); }
});
// 2. 傳遞匿名物件 (具體類別實例)
class MyCallback implements Callback {
public void execute() { System.out.println("具體類別"); }
}
processor.process(new MyCallback()); // 有名類別的匿名實例
// 3. Lambda (Java 8+ 推薦)
processor.process(() -> System.out.println("Lambda"));
語法合法性對照
| 參數類型 | 可傳匿名物件 | 可傳匿名類別 | 說明 |
| 介面 | ❌ | ✅ | 需實作介面方法 |
| 抽象類 | ❌ | ✅ | 需實作抽象方法 |
| 具體類 | ✅ | ✅ (匿名子類別) | 可直接 new 或匿名繼承覆寫 |
| 函數式介面 | ❌ | ✅ | Java 8+ 推薦用 Lambda |
核心差異
- 匿名物件:
new ConcreteClass() — 型別為 ConcreteClass,無新型別產生
- 匿名類別:
new SuperType() { ... } — 編譯器產生隱式類別 EnclosingClass$1,繼承/實作 SuperType
- 兩者皆為運算式,可直接作為引數傳遞
實務建議
- Java 8+:優先使用 Lambda 表達式 替代單方法介面的匿名類別
- 需覆寫多個方法或存取外部變數:使用匿名類別
- 單純建立物件傳遞:用具體類別的匿名物件
- 外部變數需為
final 或 effectively final (Java 8+)