1. 替代传统常量类

在枚举出现前,通常用 public static final 定义常量:

public class Status {
public static final int PENDING = 0;
public static final int APPROVED = 1;
public static final int REJECTED = 2;
}
这种方式存在类型不安全、缺少命名空间、打印不直观等问题。

使用枚举后:
public enum Status {
PENDING, APPROVED, REJECTED
}
类型安全:方法签名 setStatus(Status s) 可杜绝非法值传入。

可读性强:Status.PENDING.toString() 直接输出 “PENDING”。

内置方法:values() 遍历所有常量,ordinal() 返回序号,name() 返回名称。

支持 switch:可直接配合 switch-case 使用。

进阶用法可为常量关联字段:
public enum ErrorCode {
SUCCESS(200, “成功”),
NOT_FOUND(404, “未找到”),
ERROR(500, “服务器内部错误”);
private final int code;
private final String msg;
ErrorCode(int code, String msg) { this.code = code; this.msg = msg; }
public int getCode() { return code; }
public String getMsg() { return msg; }
}

2. 实现单例模式

利用枚举天生线程安全、防反射和防序列化破坏的特性,可写出最简洁的单例。

public enum Singleton {
INSTANCE;
public void doSomething() { … }
}
调用:Singleton.INSTANCE.doSomething();

《Effective Java》推荐这种方式:枚举单例不会被反射实例化(Constructor.newInstance() 会抛出异常),反序列化也不会创建新实例,是目前最安全的单例实现。

3. 策略模式

定义抽象方法,每个枚举常量分别实现,即可形成策略模式。

public enum PaymentMethod {
WECHAT {
@Override
public void pay(double amount) {
System.out.println(“微信支付:” + amount + “ 元”);
}
},
ALIPAY {
@Override
public void pay(double amount) {
System.out.println(“支付宝支付:” + amount + “ 元”);
}
};
public abstract void pay(double amount);
}
使用时直接:

PaymentMethod method = PaymentMethod.WECHAT;
method.pay(100.00);
新增一种支付方式只需添加一个枚举常量并实现抽象方法,无需修改已有代码,符合开闭原则。

4. 状态机

通过抽象方法定义状态转换规则,可清晰表达有限状态机。

public enum OrderState {
PENDING {
@Override public OrderState next() { return CONFIRMED; }
},
CONFIRMED {
@Override public OrderState next() { return SHIPPED; }
},
SHIPPED {
@Override public OrderState next() { return DELIVERED; }
},
DELIVERED {
@Override public OrderState next() { return this; }
};
public abstract OrderState next();
}
结合字段还能记录触发事件、附加数据等,使状态流转逻辑集中在枚举内,减少分散的 if-else。

5. EnumSet 与 EnumMap

Java 为枚举专门提供了高效集合:

EnumSet pendingOrApproved = EnumSet.of(Status.PENDING, Status.APPROVED);

EnumMap<Status, String> map = new EnumMap<>(Status.class);
map.put(Status.PENDING, “待处理”);
EnumSet:以位向量实现,空间、时间效率极高,适用于标志位、枚举集合等场景。

EnumMap:以数组为底,键不重复,顺序为枚举定义顺序,性能优于普通 HashMap。

总结与建议

何时用枚举:固定常量集、状态机、单例、策略模式等。

注意:枚举初始化在静态块之前,构造器中避免依赖其他静态资源;枚举默认实现 Serializable 且序列化安全。

不要滥用:如果策略逻辑过于复杂或数量庞大,建议单独使用策略类,枚举仅作为工厂或选择器。

掌握枚举的这些用法,能让你的代码更简洁、安全、易于维护。