枚举
约 894 字大约 3 分钟
布欧-Lewyon
2026-05-14
enum 是 Java 5 引入的类型安全的枚举。与 int 常量或 String 常量相比,enum 提供编译期检查、自带方法,且可添加字段与行为。
基本用法
public enum Color {
RED, GREEN, BLUE
}使用时:
Color c = Color.RED;
System.out.println(c); // RED编译器会阻止非法的值:Color c = "red" 或 Color c = 123 均无法通过编译。
switch 配合枚举
switch (c) {
case RED -> System.out.println("红色");
case GREEN -> System.out.println("绿色");
case BLUE -> System.out.println("蓝色");
}switch 的分支覆盖所有枚举值时,不需要 default;如果未来新增枚举常量但未补 case,编译器会发出警告。
枚举的本质
每个 enum 类型隐式继承 java.lang.Enum,因此枚举不能再继承其他类(Java 不支持多继承),但可实现接口。枚举常量实质是该枚举类型的静态 final 实例:
// 上面的 Color 大致等价于:
public final class Color extends Enum<Color> {
public static final Color RED = new Color();
public static final Color GREEN = new Color();
public static final Color BLUE = new Color();
}因此用 == 比较两个枚举常量是安全的(引用相等),也可以用 equals。
带字段与方法的枚举
枚举可以有构造器、字段、方法。构造器只在 JVM 加载每个枚举常量时调用一次:
public enum Planet {
MERCURY(3.303e23, 2.4397e6),
VENUS(4.869e24, 6.0518e6),
EARTH(5.976e24, 6.37814e6);
private final double mass; // 质量(kg)
private final double radius; // 半径(m)
Planet(double mass, double radius) {
this.mass = mass;
this.radius = radius;
}
public double surfaceGravity() {
return 6.67300E-11 * mass / (radius * radius);
}
}double g = Planet.EARTH.surfaceGravity();- 枚举构造器默认且只能是
private(可省略),外部无法调用。 - 枚举常量列表必须在第一行,并以分号结束后再写其他成员。
常用内建方法
| 方法 | 作用 |
|---|---|
values() | 返回所有常量数组,顺序与声明一致 |
valueOf(String) | 按名称查找常量,未找到抛 IllegalArgumentException |
ordinal() | 返回常量声明的序号(从 0 开始),避免在业务逻辑中依赖 |
name() | 返回常量名称字符串 |
for (Planet p : Planet.values()) {
System.out.println(p.name() + " 重力: " + p.surfaceGravity());
}
Planet p = Planet.valueOf("EARTH"); // Planet.EARTH为什么不要依赖 ordinal()
如果调整常量声明顺序或插入新常量,所有依赖 ordinal() 的代码都会出错。替代方案:在构造器里传入显式编号或用字段标注。
枚举实现接口
枚举可实现一个或多个接口,每个常量共用同一套实现:
public interface Describable {
String description();
}
public enum Operation implements Describable {
ADD, SUBTRACT, MULTIPLY, DIVIDE;
@Override
public String description() {
return switch (this) {
case ADD -> "加法";
case SUBTRACT -> "减法";
case MULTIPLY -> "乘法";
case DIVIDE -> "除法";
};
}
}小结
enum是类型安全的枚举常量集,编译期检查比int/String常量更可靠。- 枚举常量是
static final实例,可用==比较;switch分支覆盖所有常量时可省略default。 - 枚举可带构造器(隐式
private)、字段和方法;常量列表必须第一行,分号结尾。 - 内建方法:
values()(所有常量数组)、valueOf()(按名称查找)、name()、ordinal()(避免业务依赖)。 - 枚举可实现接口,但不能继承其他类。
- 易错:
ordinal()返回常量声明顺序的序号——插入或重排常量会导致序号变化。如需编号,在构造器中用显式字段(如int id)代替依赖ordinal()。 - 思考任务:定义一个
Weekday枚举(含MON~SUN),每个常量带一个中文名字段;编写静态方法fromChinese(String)将中文名映射回枚举常量。
上一节:抽象类与接口
下一节:String 与日期时间
