無名稱的類定義與實例化合二為一的語法糖:
new InterfaceOrClass() {
// 類體:實現方法、定義字段
};
OuterClass$1.class 等合成類;new 創建新實例;{...});static 成員(常量 static final 除外);this 指向匿名類自身,外部類用 OuterClass.this。frame.addWindowListener(new WindowAdapter() {
@Override public void windowClosing(WindowEvent e) {
System.exit(0);
}
});
new Thread(new Runnable() {
@Override public void run() { doWork(); }
}).start();
Collections.sort(list, new Comparator<User>() {
@Override public int compare(User u1, User u2) {
return u1.getAge() - u2.getAge();
}
});
abstract class Worker {
public final void execute() {
before();
doWork(); // 子類/匿名類實現
after();
}
protected void before() {}
protected abstract void doWork();
protected void after() {}
}
// 使用
new Worker() {
@Override protected void doWork() { System.out.println("具體任務"); }
}.execute();
public void demo(final int base) {
int local = 10; // Java 8+ 實際上 final
Runnable r = new Runnable() {
@Override public void run() {
System.out.println(base + local); // 捕獲副本
}
};
// local = 20; // 編譯錯誤:破壞實際上 final
}
final 字段;final,Java 8+ 編譯器推斷「實際上 final」。| 特性 | 匿名內部類 | Lambda |
|---|---|---|
| 適用目標 | 任意接口/類 | 僅函數式接口(單抽象方法) |
| this 指向 | 匿名類實例 | 外部類實例 |
| 序列化 | 實現 Serializable 即可 | 目標類型需 Serializable |
| 性能 | 創建類對象 | invokedynamic + LambdaMetafactory,更輕量 |
| 可讀性 | 冗長 | 簡潔 |
建議:函數式接口優先用 Lambda;需實現多方法、繼承類、定義字段/構造邏輯時用匿名內部類。
Serializable,需顯式實現且外部類也需可序列化;OuterClass$1,命名內部類更利於診斷。