Java枚举类天然适合实现状态机,因其单例、类型安全、不可变且可预定义全部合法状态;通过添加私有属性、带参构造函数和业务方法(如状态转移、描述获取、权限校验),可构建功能丰富、易维护的状态机。

Java 枚举类天然适合实现状态机,因为枚举实例是单例、类型安全、不可变且可预定义全部合法状态。通过为枚举添加私有属性、带参构造函数、业务方法(如状态转移逻辑、描述获取、权限校验等),就能构建出功能丰富、易维护的状态机。
定义状态属性与构造函数
每个枚举常量可看作一个独立对象,支持携带字段并用构造函数初始化。例如管理订单状态:
public enum OrderStatus {
CREATED("已创建", 1, false),
PAID("已支付", 2, true),
SHIPPED("已发货", 3, true),
COMPLETED("已完成", 4, true),
CANCELLED("已取消", 0, false);
private final String desc;
private final int level;
private final boolean isTerminal;
// 私有构造函数,用于初始化每个枚举实例的属性
OrderStatus(String desc, int level, boolean isTerminal) {
this.desc = desc;
this.level = level;
this.isTerminal = isTerminal;
}
// 提供只读访问方法
public String getDesc() { return desc; }
public int getLevel() { return level; }
public boolean isTerminal() { return isTerminal; }
}
这样每个状态自带语义信息和行为特征,避免散落的常量或 Map 映射。
封装状态转移规则
在枚举内部定义合法转移逻辑,把“哪些状态能转到哪些状态”收口管理,提升可读性和安全性:
立即学习“Java免费学习笔记(深入)”;
// 在 OrderStatus 枚举中新增方法
public boolean canTransitionTo(OrderStatus next) {
if (this == CANCELLED) return false; // 已取消不可再变更
if (next == CANCELLED) return this != COMPLETED; // 完成后不可取消
if (this == COMPLETED) return false;
return next.level > this.level; // 仅允许升序流转(简化示例)
}
// 使用示例
if (current.canTransitionTo(OrderStatus.PAID)) {
current = OrderStatus.PAID;
}
- 转移逻辑内聚在枚举中,调用方无需记忆规则
- 可结合注解、配置或外部策略扩展复杂条件(如角色、时间、金额)
- 返回 boolean 或抛异常(如 IllegalStateException)取决于设计偏好
支持反向查找与元数据扩展
实际使用中常需根据 code、name 或 level 查找对应枚举值。建议在枚举中内置静态查找方法,并支持扩展字段(如操作按钮、颜色标识、国际化 key):
private static final Map<String, OrderStatus> BY_CODE = Arrays.stream(values())
.collect(Collectors.toMap(e -> e.name(), e -> e));
public static OrderStatus fromCode(String code) {
return BY_CODE.getOrDefault(code, null);
}
// 扩展字段示例:前端展示所需图标 class
private final String iconClass;
OrderStatus(String desc, int level, boolean isTerminal, String iconClass) {
this(desc, level, isTerminal);
this.iconClass = iconClass;
}
// 构造时传入:CREATED("已创建", 1, false, "icon-draft")
避免每次使用都新建 Map 或依赖反射,性能好且类型安全。
配合状态机框架或轻量封装使用
纯枚举适合简单线性状态机;若需事件驱动、持久化、监听或并行状态,可将枚举作为核心状态载体,外层套一层状态机包装类:
- 用枚举表示所有可能状态(State)
- 用普通类(如 OrderStateMachine)持有当前状态、执行 transition 方法
- transition 内部调用枚举的 canTransitionTo 并更新状态字段
- 可注入监听器,在状态变更前后触发日志、通知或校验
这样既保持枚举的简洁性,又具备扩展能力,不耦合业务流程。


















