在一個類別內部定義另一個類別,稱為巢狀類。分為兩大類:
static 修飾。public class StaticTest {
private static String name = "javaJohn";
private String id = "X001";
static class Person {
private String address = "Chengdu";
public String mail = "test@mail.com";
public void display() {
System.out.println(name); // 僅能存取外部靜態成員
// System.out.println(id); // 編譯錯誤:無法存取非靜態成員
}
}
public void printInfo() {
Person p = new Person();
p.display();
System.out.println(p.mail); // 外部類可存取內部類私有成員
}
}
特點:
StaticTest$Person.class。public class Outer {
int outer_x = 100;
class Inner {
public int y = 10;
private int z = 9;
public void display() { System.out.println("outer_x: " + outer_x); }
}
void test() {
Inner inner = new Inner();
inner.display();
System.out.println(inner.z); // 外部類可存取內部類私有成員
}
class InnerTwo {
Inner inner = new Inner();
void show() { inner.display(); }
}
}
規則:
class Outer {
public void doSomething() {
final int a = 10; // Java 8+ 可隱含 final
class Inner {
public void seeOuter() { System.out.println(a); }
}
new Inner().seeOuter(); // 僅能在方法內實例化
}
}
限制:
Car car = new Car() {
@Override public void drive() { System.out.println("Driving another car!"); }
};
car.drive(); // 實際執行匿名子類方法
Vehicle v = new Vehicle() {
@Override public void drive() { System.out.println("Driving a car!"); }
};
v.drive(); // 實作介面的匿名類
b.doStuff(new Foo() {
@Override public void foo() { System.out.println("foofy"); }
});
.class 檔,命名為 Outer$Inner.class、Outer$1.class(匿名類)。private/protected 修飾。new Outer().new Inner()。善用內部類可實現封裝、回調、事件監聽等模式。匿名內部類是 Java 7 以前實現函數式風格的主要手段,Java 8+ 建議改用 Lambda 表達式。