应直接switch枚举状态值,属性仅在case内按需使用以增强可读性与行为收敛;每个case保持轻量、只调度不实现;优先用switch表达式返回结构化结果;禁用default以强制穷尽处理。

直接用 switch 处理带自定义属性的枚举,关键不是“能不能取到属性”,而是让分支逻辑聚焦状态本身,把属性用作辅助判断或结果生成,而非主干条件。属性应服务于可读性与行为收敛,而不是把 switch 变成属性提取器。
明确枚举职责:状态即契约,属性即元数据
枚举的核心是定义一组封闭、互斥、语义明确的状态。自定义属性(如 code、desc、isFinal、retryCount)只是对每个状态的补充说明,不改变其本质。switch 分支应基于状态值 dispatch,属性在 case 内按需使用。
- 避免写成
switch(status.getCode())—— 这退化为整型判断,丢失类型安全和语义 - 正确做法是
switch(status),然后在case APPROVED:中调用status.getDesc()或status.isTerminal() - 例如订单状态枚举中,
APPROVED的retryCount = 0和timeoutMs = 30000是它固有的业务特征,不是分支依据
case 内只调度,不堆砌业务实现
每个 case 应保持轻量,仅决定“谁来处理”或“返回什么”,不嵌入完整业务流程。复杂逻辑抽离为独立方法或服务,由枚举状态触发调用。
- 好:
case PENDING -> orderService.startProcessing(order); - 差:
case PENDING: { order.setStatus(PENDING); notifyUser(); logEvent(); startTimer(); ... } - 这样设计后,新增状态(如
VERIFIED)只需加一个 case 并绑定对应服务,不扰动原有逻辑
利用 Java 14+ switch 表达式返回结构化结果
当分流目标是生成统一类型的结果(如响应消息、DTO、策略对象),优先用 switch 表达式,避免临时变量和重复 return。
- 示例:根据错误枚举返回标准化提示
return switch(error) {case NOT_FOUND -> new ApiResult(404, "资源不存在", error.getHint());case VALIDATION_FAILED -> new ApiResult(400, "参数校验失败", error.getDetails());case SYSTEM_ERROR -> new ApiResult(500, "服务暂不可用", null);default -> throw new IllegalStateException("未处理的错误类型: " + error);};
禁用 default,强制穷尽性检查
枚举是封闭集合,default 分支会掩盖新增状态未被处理的风险。编译器无法警告你漏了 case,但主动去掉 default 能让缺失覆盖在编译时报错(尤其配合 IDE 提示)。
- Java 中不写 default,所有枚举值必须显式列出
- 若真有未知情况(如反序列化失败),用
throw new IllegalArgumentException(...)替代 print 或静默 fallback - 团队协作时,这能确保每次加新枚举值,都同步补全所有 switch 使用点











