内部类与枚举
学习成员内部类、静态内部类、匿名类、enum 枚举
内部类与枚举
Java 允许在一个类里面再定义一个类——这就是内部类。它有 4 种形式,各自适用不同场景。
学完本章你将: 区分 4 种内部类的用途、匿名类的实战、enum 枚举。
四种内部类概览
| 类型 | 定义位置 | 能访问外部成员 | 常用场景 |
|---|---|---|---|
| 成员内部类 | 类里面 | ✅ | 紧密关联的辅助类 |
| 静态内部类 | 类里面 + static | ❌ | 独立于外部实例的辅助类 |
| 局部类 | 方法里面 | ✅ | 方法内临时封装逻辑 |
| 匿名类 | new 后面直接写 | ✅ | 一次性接口实现(Lambda 简化了它) |
成员内部类 —— 访问外部类的一切
编译后会产生 Outer$Inner.class 文件。内部类对象持有对外部类对象的隐式引用。
java
public class Outer {
private String name = "Outer";
public class Inner {
public void print() {
System.out.println(name); // 直接访问外部类的 private 成员
}
}
}
Outer outer = new Outer();
Outer.Inner inner = outer.new Inner(); // 必须先有外部对象
inner.print(); // "Outer"
匿名内部类 —— 一次性实现
不需要单独定义类名,直接 new 接口/父类 { 实现 }。它是 Lambda 出现前的主要回调方式。
java
// 传统匿名类
Runnable task = new Runnable() {
@Override
public void run() {
System.out.println("匿名类执行");
}
};
new Thread(task).start();
// Lambda 简化后(等价)
new Thread(() -> System.out.println("Lambda 执行")).start();
// 匿名类还能用双括号初始化集合
List<String> list = new ArrayList<>() {{
add("A"); add("B"); add("C");
}}; // ⚠️ 这实际创建了 ArrayList 的子类,不是普通 ArrayList
枚举 —— 有限的常量集合
当变量只能取几个固定值(星期、季节、状态),用 enum 比 int 常量更安全——编译器会检查是否传了非法值。
java
public enum Day {
MONDAY, TUESDAY, WEDNESDAY, THURSDAY, FRIDAY, SATURDAY, SUNDAY
}
Day today = Day.WEDNESDAY;
// Day x = Day.HELLO; // ❌ 编译错误,没有这个值
// 枚举可以带属性和方法
public enum Planet {
MERCURY(3.303e+23, 2.4397e6),
EARTH(5.976e+24, 6.378e6);
private final double mass;
private final double radius;
Planet(double mass, double radius) { this.mass = mass; this.radius = radius; }
public double surfaceGravity() { return 6.673E-11 * mass / (radius * radius); }
}
System.out.println(Planet.EARTH.surfaceGravity());
💡 enum vs 常量类:
enum天生不可变、自带values()遍历、switch友好。用public static final int表示状态则是旧式写法,容易传错值。
public double surfaceGravity() {
return 6.67300E-11 * mass / (radius * radius);
}
}
System.out.println(Planet.EARTH.surfaceGravity());