java switch用enum时编译器强制穷尽匹配,新增枚举值会报错;禁用ordinal()作分支依据;null输入直接抛npe便于定位;需确保反序列化与数据库映射兼容。

switch 用 enum 时编译器能帮你拦住非法值
Java 的 switch 在匹配 enum 类型时,编译期就强制要求覆盖所有枚举常量(除非加 default),这是最直接的类型安全体现。如果枚举新增一个值,而你漏了对应 case,且没写 default,JDK 14+ 会直接报错:error: the switch expression does not cover all possible input values。
这种检查只在 switch 表达式或语句针对 enum 本身时生效,换成 String 或 int 就完全没这层保护。
- 必须是
enum类型变量直接作为switch的操作数,不能先转成String或序号再切 - 使用
switch表达式(switch (e) { case A -> ... })比传统语句更严格,更容易触发穷尽性检查 - 如果写了
default,编译器就不再强制穷尽,但你也失去了“漏 case 就报警”的好处
别把 enum.ordinal() 当 switch 分支依据
用 ordinal() 转成数字再 switch,看似可行,实则埋雷:一旦调整枚举声明顺序,所有依赖序号的逻辑就悄悄错位,而且编译器完全不提醒。
比如 Status.ACTIVE.ordinal() 原来是 0,你写 case 0:,后来在它前面加了个 PENDING,ACTIVE 就变成 1,但代码照常编译通过,运行时才出问题。
你接手一个需求时,是不是经常这样:"改一个小字段 → 结果把不相关的代码也改了"、"需求说得很模糊 → 做着做着发现跑偏了"、"数据库加个字段 → 上线才发现漏了数据兼容"、"做了个新功能 → 一个月后自己都忘了当时怎么设计的"、"写到一半被中断 → 再回来不知道从哪继续";这个 Skill 就是专门解决这些问题的。 它会自动探测你的项目环境(JDK、Spring Boot、ORM、数据库、前端框架),记在
- 永远用枚举常量名写
case,例如case ACTIVE:,而不是case 0: -
ordinal()只适合做序列化索引或底层存储映射,不该出现在业务分支逻辑里 - IDE 有时会提示 “Replace ordinal() with enum constant”,建议接受
switch 表达式 + enum 是 null 安全的天然搭档
当 switch 操作数是 enum 类型时,如果传入 null,运行时抛的是 NullPointerException,而不是静默失败或进入 default。这反而是好事——它强迫你在上游处理空值,避免逻辑被掩盖。
对比用 String 做 switch,null 会直接抛 NullPointerException,但没人知道是哪个 case 没兜住;而 enum 的 null 报错位置清晰,堆栈指向 switch 那一行。
- 如果允许
null输入,必须显式判断,例如if (status == null) {...} else switch (status) {...} - 不要依赖
default捕获null——它捕不到,null会提前炸掉 - Lombok 的
@NonNull或 Spring 的@NotNull可以配合用在参数上,把空值拦截得更早
从 int/String 切换到 enum switch 时注意兼容性
老代码常用 int 码值或 String 标识状态,改成 enum + switch 时,最容易忽略反序列化兼容和数据库字段映射。
比如数据库存的是 tinyint,Java 层直接映射成 enum,但没配好 MyBatis 的 TypeHandler,读出来就是 null,然后 switch 炸了——不是语法问题,是数据链路断了。
- Spring Boot 2.5+ 默认启用
Enum的字符串序列化,若要继续用数字,需配置spring.jackson.serialization.write-enums-using-to-string=false - MyBatis 用
@EnumValue或自定义TypeHandler显式控制数据库映射逻辑 - 前后端接口若仍传数字,Java 层别用
enum.valueOf(),改用静态方法按码值查找,避免IllegalArgumentException
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南










