定义
在 Java 中,enum(枚举)是一种特殊的类,用于定义固定数量的常量集合。它从 JDK 5(Java 1.5) 开始引入,目的是替代传统的 public static final int 常量,提供类型安全、可读性强、功能丰富的常量管理方式
java
public enum Day {
MONDAY, TUESDAY, WEDNESDAY, THURSDAY, FRIDAY, SATURDAY, SUNDAY;
}
扩展
java
public enum Day {
MONDAY("MONDAY", 0),
TUESDAY("TUESDAY", 1);
}
相当于
java
public final class Day extends java.lang.Enum<Day> {
public static final Day MONDAY = new Day("MONDAY", 0);
public static final Day TUESDAY = new Day("TUESDAY", 1);
// ... 其他常量
private Day(String name, int ordinal) {
super(name, ordinal);
}
public static Day[] values() { /* 返回所有常量 */ }
public static Day valueOf(String name) { /* 根据名字返回常量 */ }
}
内置常用方法
| 方法 | 作用 | 示例 |
|---|---|---|
values() |
返回所有常量数组 | Day[] days = Day.values(); |
valueOf(String) |
根据名称返回常量 | Day d = Day.valueOf("MONDAY"); |
ordinal() |
返回声明索引 | Day.MONDAY.ordinal() → 0 |
name() |
返回常量名称 | Day.MONDAY.name() → "MONDAY" |
compareTo() |
按声明顺序比较 | MONDAY.compareTo(TUESDAY) → -1 |
在 Java 中,枚举类(enum)的构造函数参数数量没有硬性限制
java
public enum Planet {
EARTH(1, "blue", 9.8, true, "Solar System", ...); // 理论上可继续添加
Planet(double mass, String color, double gravity, boolean habitable, String system /*, ...*/) {
// 构造逻辑
}
}
| 问题 | 说明 |
|---|---|
| 代码可读性崩溃 | 超过 5-10 个参数已难以维护(违反 Clean Code 原则) |
| 编译错误 | 某些 IDE 或编译器可能提前报错(如 Eclipse 限制方法参数 ≤ 255,但实际更早失败) |
| 字节码膨胀 | 大量参数导致 .class 文件臃肿 |
添加字段,构造方法等
在 Java 中,enum(枚举)不仅可定义常量列表,还可以像普通类一样:
- 添加字段(成员变量)
- 定义构造函数
- 声明方法(包括抽象方法)
- 实现接口
这使得 enum 非常强大,适用于需要为每个常量附加数据或行为的场景。
java
public enum Planet {
// 枚举常量(必须在最前面,调用构造函数)
MERCURY(3.303e+23, 2.4397e6),
VENUS (4.869e+24, 6.0518e6),
EARTH (5.976e+24, 6.37814e6),
MARS (6.421e+23, 3.3972e6);
// 字段(通常为 private final)
private final double mass; // 质量(kg)
private final double radius; // 半径(m)
// 构造函数(只能是 private 或 package-private,默认 private)
Planet(double mass, double radius) {
this.mass = mass;
this.radius = radius;
}
// 方法
public double getMass() { return mass; }
public double getRadius() { return radius; }
// 计算表面重力:g = G * M / r^2
public double surfaceGravity() {
return 6.67300E-11 * mass / (radius * radius);
}
// 计算某物体在该星球上的重量
public double surfaceWeight(double otherMass) {
return otherMass * surfaceGravity();
}
}
java
public class Main {
public static void main(String[] args) {
Planet earth = Planet.EARTH;
System.out.println("Earth's gravity: " + earth.surfaceGravity());
System.out.println("My weight on Mars: " + Planet.MARS.surfaceWeight(70)); // 70kg 人在火星的重量
}
}
内置常用方法
高级用法:每个常量有不同行为(抽象方法)
java
public enum Operation {
PLUS {
public double apply(double x, double y) { return x + y; }
},
MINUS {
public double apply(double x, double y) { return x - y; }
},
TIMES {
public double apply(double x, double y) { return x * y; }
},
DIVIDE {
public double apply(double x, double y) { return x / y; }
};
// 抽象方法 → 每个常量必须实现
public abstract double apply(double x, double y);
}
java
double result = Operation.PLUS.apply(5, 3); // 8.0
| 特性 | 说明 |
|---|---|
| 枚举常量必须在第一行 | 所有 CONSTANT(...) 必须出现在字段/方法之前 |
构造函数只能是 private |
不能 public 或 protected(防止外部 new) |
字段建议用 final |
枚举常量通常是不可变的 |
| 可以实现接口 | enum MyEnum implements Runnable { ... } |
| 不能继承其他类 | 因为 enum 隐式继承 java.lang.Enum(Java 不支持多继承) |
| 可以有静态方法/字段 | 如 values(), valueOf(String) 是自动生成的 |
总结
Java 的 enum 远不止是"常量集合",它是一个功能完整的类,支持:
字段 + 构造函数 + 方法 + 接口 + 多态行为
合理使用能让代码更安全、清晰、可维护,是 Java 中被低估的强大特性。