Java 枚举 enum
枚举(enum)用来表示一组固定的常量,如季节、星期、订单状态。相比 int/String 常量,枚举类型安全、自带方法、还能携带字段与行为,是 Java 5 引入后的推荐做法。
定义与基本用法
用 enum 关键字定义枚举,成员就是一组常量,之间用逗号分隔:
enum Season {
SPRING, SUMMER, AUTUMN, WINTER
}
// —— 片段需放进 main 方法中运行 ——
Season s = Season.SPRING;
System.out.println(s);
// 输出:SPRING
用枚举替换常量
旧写法用 int 常量表达状态,传入 1、2 以外的"魔法数字"也不会报错;枚举把取值限定在定义好的几个值之内,编译器就能帮你把关:
// 旧做法:魔法数字,传错值也发现不了
int season = 1; // 到底哪个是春天?
// 新做法:类型明确,只能取枚举值
Season now = Season.SUMMER;
枚举内置方法
每个枚举都自带 name()、ordinal(),还提供 values() 与静态 valueOf():
Season[] all = Season.values(); // 取出全部枚举值
System.out.println(all.length);
Season sp = Season.valueOf("SPRING"); // 字符串转枚举
System.out.println(sp.ordinal()); // 声明顺序下标,从 0 开始
System.out.println(sp.name()); // 常量名
// 输出:4
// 输出:0
// 输出:SPRING
带构造、字段与方法的枚举
枚举可以像类一样拥有字段、构造方法和普通方法。构造方法默认是 private 的,在声明常量时传入参数:
enum Season {
SPRING("春"), SUMMER("夏"), AUTUMN("秋"), WINTER("冬");
private final String cn;
Season(String cn) { this.cn = cn; }
public String getCn() { return cn; }
}
// —— 片段需放进 main 方法中运行 ——
System.out.println(Season.AUTUMN.getCn());
// 输出:秋
switch 配合枚举
switch 可以直接分支枚举,case 后面写常量名(不带枚举前缀):
Season now = Season.SUMMER;
switch (now) {
case SPRING: System.out.println("播种"); break;
case SUMMER: System.out.println("游泳"); break;
default: System.out.println("其他");
}
// 输出:游泳
示例:简单状态机
给枚举加 next() 方法,就能模拟"订单状态流转"这种简单状态机:
enum OrderState {
NEW, PAID, SHIPPED, DONE;
public OrderState next() { // 枚举可以携带行为
if (this == NEW) return PAID;
if (this == PAID) return SHIPPED;
return DONE;
}
}
// —— 片段需放进 main 方法中运行 ——
OrderState st = OrderState.NEW;
System.out.println(st.next());
// 输出:PAID
EnumSet / EnumMap 简介
专为枚举设计的高性能集合:EnumSet 存枚举元素,EnumMap 的键只能是枚举:
EnumSet<Season> es = EnumSet.of(Season.SPRING, Season.WINTER);
System.out.println(es.contains(Season.SPRING));
// 输出:true
枚举把散落的常量变成有类型的对象:值域受限更安全,自带 name/ordinal/values 等方法,还能挂字段与方法;配合 switch 与 EnumSet/EnumMap,是描述固定集合的最佳选择。