內部類(Inner Class)定義在另一個類內部,提供了更好的封裝性:可訪問外部類所有成員(含 private)、隱藏實現細節、實現多重繼承效果、便於編寫回調與事件驅動代碼。編譯後生成 Outer$Inner.class 文件。
public class Outer {
private int outerField = 100;
public class Inner {
public void accessOuter() {
System.out.println(outerField); // 直接訪問
System.out.println(Outer.this.outerField); // 顯式調用
}
}
}
// 創建實例:需先有外部類實例
Outer outer = new Outer();
Outer.Inner inner = outer.new Inner();
Outer.thispublic class Outer {
private static int staticField = 200;
private int instanceField = 300;
public static class StaticInner {
public void access() {
System.out.println(staticField); // ✅ 可訪問靜態成員
// System.out.println(instanceField); // ❌ 無法訪問實例成員
}
}
}
// 創建:無需外部類實例
Outer.StaticInner si = new Outer.StaticInner();
public class Outer {
private int field = 400;
public void method(final String param) { // JDK 8+ 可省略 final
class LocalInner {
public void print() {
System.out.println(field); // 訪問外部類成員
System.out.println(param); // 訪問方法參數(需 final 或 effectively final)
}
}
new LocalInner().print();
}
}
final 或「實際最終」(不再修改)// 實現接口
Runnable r = new Runnable() {
@Override public void run() { System.out.println("Running..."); }
};
// 繼承類
Comparator cmp = new Comparator<>() {
@Override public int compare(String a, String b) {
return b.length() - a.length(); // 降序
}
};
// 帶參構造器調用(需父類有對應構造器)
List list = new ArrayList<>() {{
add("init"); // 雙大括號初始化(反模式,慎用)
}};
| 內部類類型 | 外部類實例成員 | 外部類靜態成員 | 方法局部變量 | 創建方式 |
|---|---|---|---|---|
| 成員內部類 | ✅ 直接訪問 | ✅ | ❌ | outer.new Inner() |
| 靜態內部類 | ❌ | ✅ | ❌ | new Outer.StaticInner() |
| 局部內部類 | ✅ | ✅ | ✅ (final/effectively final) | 方法內 new Local() |
| 匿名內部類 | ✅ | ✅ | ✅ (final/effectively final) | 表達式中 new Type(){} |
Externalizable