代碼片段中 new Thread() { public void run() { ... } }.start(); 乍看像「在方法裡隨意創建類」,實則是 匿名內部類 的標準用法。編譯器會自動生成一個實現 Runnable 或繼承 Thread 的具體類,並立即實例化。
// 編譯器生成的隱式類(簡化)
class MyThread extends Thread {
private final Runnable task; // 捕獲的外部 final 變數
MyThread(Runnable task) { this.task = task; }
@Override public void run() { task.run(); }
}
// 原代碼等價於
new MyThread(new Runnable() {
public void run() {
listData.add("選項" + listData.size());
list.setListData(listData);
}
}).start();
final 修飾(或實際上不可變)的局部變數。Java 8+ 隱含 effectively final,無需寫 final。new Thread() { ... } 沒有變數名,創建後直接調用 .start(),用完即棄,適合一次性任務。Thread.sleep() 等可能拋 InterruptedException 的阻塞調用。捕獲後程序不會崩潰,會繼續執行 catch 後的代碼;若不捕獲,異常會拋出當前線程,導致線程終止,甚至影響主線程(視線程組而定)。EventQueue.invokeLater(runnable) 將 UI 更新拋給事件分發線程(EDT),這是 Swing 多線程編程的核心規範。「方法裡可以隨意創建類」 —— 錯。匿名內部類有嚴格語法限制:只能繼承一個類或實現一個介面,不能定義構造函數(但可用實例初始化塊
{ }),不能定義靜態成員(常量除外)。
理解匿名內部類本質是「編譯器生成具體類 + 立即實例化」,即可輕鬆看懂各種 new Interface() { ... }、new Parent() { ... } 寫法。搭配 Lambda(Java 8+)更能簡化單方法介面的實例化:new Thread(() -> { ... }).start()。