Java 中定義在另一個類內部的類稱為嵌套類,分為兩大類:
static 修飾static 修飾,又分三種:
本質是頂層類,僅借用外部類命名空間:
public class StaticTest {
private static String name = "javaJohn";
private String id = "X001";
static class Person {
private String address = "China";
public String mail = "test@yahoo.com";
public void display() {
// System.out.println(id); // 編譯錯誤:無法訪問非靜態成員
System.out.println(name); // 僅能訪問靜態成員
System.out.println(address);
}
}
public void printInfo() {
Person p = new Person();
p.display();
System.out.println(p.mail); // 可訪問公有/私有成員
}
}
關鍵點:靜態嵌套類無法直接訪問外部類非靜態成員;外部類需建立實例才能訪問內部類成員。
擁有外部類實例的隱含引用,可自由訪問外部類所有成員 (含私有):
public class Outer {
int outer_x = 100;
class Inner {
public void display() { System.out.println(outer_x); }
private void display2() { System.out.println(outer_x); }
}
void test() {
Inner inner = new Inner();
inner.display();
inner.display2(); // 內部類私有方法外部類也能訪問
System.out.println(inner.y); // 訪問內部類成員
}
class InnerTwo {
Inner innerx = new Inner();
public void show() { innerx.display(); } // 同級內部類需實例化訪問
}
}
作用域:內部類僅在外部類作用域內可見。
定義在方法內部,作用域僅限該方法:
public class FunOuter {
int out_x = 100;
public void test() {
class Inner { // 方法局部類
void display() { System.out.println(out_x); }
}
new Inner().display();
}
public void showStr(String str) {
final String str3 = "final Str"; // 僅能訪問 final/實際最終變量
class InnerTwo {
public void testPrint() { System.out.println(str3); }
}
}
}
限制:不能使用 public/private/protected/static 修飾;只能訪問方法的 final 或 effectively final 變量。
無名稱、即時建立實例,常用於事件監聽器:
public class AnonymousDemo extends Applet {
public void init() {
addMouseListener(new MouseAdapter() { // 匿名類繼承 MouseAdapter
public void mousePressed(MouseEvent me) {
showStatus("Mouse Pressed!");
}
});
}
public void showStatus(String str) { System.out.println(str); }
}
特點:可訪問外部類成員;常用於介面回調、事件處理。
public class Layer {
private String testStr = "testStr";
class Person {
String name;
Email email; // 內部類的內部類
class Email { String mailID, mailNetAddress; ... }
}
class ChildLayer extends Layer { // 內部類繼承外部類
void print() { System.out.println(super.testStr); }
}
class OfficePerson extends Person { // 內部類繼承同級內部類
void show() { System.out.println(name + " " + getEmail()); }
}
}
| 類型 | 適用場景 | 注意事項 |
|---|---|---|
| 靜態嵌套類 | 工具類、輔助類、與外部類邏輯相關但無狀態依賴 | 首選,無外部實例引用,記憶體效率高 |
| 成員內部類 | 需要訪問外部實例狀態、實現複雜協作邏輯 | 持有外部引用,注意記憶體洩漏 |
| 局部內部類 | 方法內邏輯封裝、一次性使用 | 作用域極小,編譯後生成獨立 class 檔 |
| 匿名內部類 | 介面單方法實現、事件監聽、Lambda 前身 | Java 8+ 建議改用 Lambda 表達式 |