在類內部聲明的類稱為內部類,外部類稱為外部類。按聲明位置和修飾符分四類:
| 類型 | 聲明位置 | 修飾符 | 訪問外部類成員 | 創建方式 |
|---|---|---|---|---|
| 成員內部類 | 類內、方法外 | 可 static/訪問控制符 | 非靜態:全部(含 private) 靜態:僅 static | 非靜態:outer.new Inner()靜態: new Outer.StaticInner() |
| 局部內部類 | 方法/代碼塊內 | 無修飾符 | 最終/實際上 final 的局部變量 + 外部類全部 | 方法內 new LocalInner() |
| 匿名內部類 | 表達式位置 | 無名、無構造器 | 同局部內部類 | new Interface/Parent() { ... } |
| 靜態嵌套類 | 類內、方法外 | static | 僅 static 成員 | new Outer.Nested() |
Outer.class
Outer$Inner.class // 非靜態成員內部類
Outer$1.class // 匿名內部類 (按順序編號)
Outer$2$Local.class // 局部內部類 (方法內編號$類名)
Outer$StaticNested.class // 靜態嵌套類
每個內部類編譯為獨立 .class 文件。
Outer.this 隱式字段,構造器自動綁定。private)。Inner in = new Inner(); in.method();this)。Outer.this 引用,獨立於外部類實例。static 成員。final)。static 成員(枚舉/介面除外)。new SuperType/Interface() { // 體 }{ ... } 替代。public class Outer {
private int outerField = 10;
private static int staticField = 20;
public class Inner {
public void access() {
System.out.println(outerField); // 直接訪問
System.out.println(staticField);
System.out.println(Outer.this.outerField); // 顯式外部引用
}
}
public void test() {
Inner in = new Inner(); // 隱式傳遞 this
in.access();
}
}
// 外部創建
Outer outer = new Outer();
Outer.Inner inner = outer.new Inner();
inner.access();
public class Outer {
private static int staticField = 100;
public static class Nested {
public void print() {
System.out.println(staticField); // 僅 static
}
}
}
// 獨立創建,無需外部實例
Outer.Nested nested = new Outer.Nested();
nested.print();
// 匿名內部類 (JDK 7 風格)
button.addActionListener(new ActionListener() {
@Override public void actionPerformed(ActionEvent e) {
System.out.println("clicked");
}
});
// Lambda (JDK 8+,函數式介面單方法)
button.addActionListener(e -> System.out.println("clicked"));
// 複雜邏輯仍需匿名類/具體類
Runnable task = new Runnable() {
private int counter = 0; // 狀態字段
@Override public void run() {
System.out.println("Run " + ++counter);
}
};
Map.Entry、Builder 模式)。static class),無需外部實例時首選。static 內部類,避免匿名類。static 內部類 + WeakReference。public static class Builder 靜態嵌套。// File: TwoClasses.java
public class TwoClasses { } // 文件名必須匹配 public 類
class AnotherClass { } // 包私有,編譯產生 AnotherClass.class
不推薦:難搜索、違反單一職責、構建工具可能報警。堅持「一文件一公共類」。