| 類型 | 定義位置 | 存取外部成員 | 可定義 static 成員 | 建立實例語法 |
|---|---|---|---|---|
| 成員內部類 | 類內部、方法外 | 所有(含 private) | 否 | Outer outer = new Outer(); Outer.Inner in = outer.new Inner(); |
| 靜態巢狀類 | 類內部、方法外 | 僅 static 成員 | 是 | Outer.StaticNested sn = new Outer.StaticNested(); |
| 區域內部類 | 方法/程式碼區塊內 | 外部類所有 + 方法 final 區域變數 | 否 | 在方法內 new LocalClass() |
| 匿名內部類 | 表達式中 | 同上 | 否 | new Interface() { ... } 或 new SuperClass() { ... } |
public class Outer {
private int value = 10;
class Inner {
void print() { System.out.println(Outer.this.value); } // 明確引用外部實例
}
}
編譯器隱式傳遞 Outer.this 給 Inner 建構子,因此 建立非靜態內部類實例前必須先有外部類實例。
Java 8 以前:只能捕獲 final 區域變數。
Java 8+:實際上不可變 即可(Effectively final),無需顯式 final。
void startTask() {
int count = 0; // effectively final
Runnable r = () -> System.out.println(count); // Lambda 也是匿名內部類的語法糖
new Thread(r).start();
}
若需初始化欄位,三種方式:
new Runnable() { { init(); } public void run() {...} };new Parent(arg) { ... } 需傳參並可 super(arg)。// 介面
public interface Callback { void onResult(String data); }
// 使用匿名類實現回調
service.fetchData(new Callback() {
@Override public void onResult(String data) { updateUI(data); }
});
// Lambda 取代(Java 8+,單一方法介面)
service.fetchData(data -> updateUI(data));
WeakReference<Outer>。Serializable 會連帶序列化外部類實例,慎用。.class 檔(Outer$Inner.class),大量匿名類會增加類載入開銷。