Java字符串switch需防NPE、标准化输入、case值为编译期常量,分支≥5时性能更优。必须null检查、trim().toLowerCase()预处理,case仅支持字面量或static final String。

Java 中用 switch 匹配字符串本身不难,但要真正安全,关键在于防 NullPointerException、处理大小写与空白、避免隐式性能陷阱。Java 7 起支持字符串 switch,但底层依赖 equals() 和 hashCode(),一旦输入不可控,就容易崩。
必须做 null 检查
字符串 switch 不接受 null,直接传入会抛出 NullPointerException,且无法用 case null: 捕获(语法非法)。最稳妥的做法是提前拦截:
- 在
switch前加if (str == null)分支,统一处理或返回默认逻辑 - 不推荐用
switch(str != null ? str : "")这类兜底,易掩盖真实问题 - 若使用 Optional,建议先
.orElse(null)或.orElse("")明确语义,再判断
标准化输入再匹配
字符串比较默认区分大小写,且前后空格会影响 equals() 结果。常见场景如用户输入命令、配置项、HTTP 参数,往往带空格或大小写混用:
你接手一个需求时,是不是经常这样:"改一个小字段 → 结果把不相关的代码也改了"、"需求说得很模糊 → 做着做着发现跑偏了"、"数据库加个字段 → 上线才发现漏了数据兼容"、"做了个新功能 → 一个月后自己都忘了当时怎么设计的"、"写到一半被中断 → 再回来不知道从哪继续";这个 Skill 就是专门解决这些问题的。 它会自动探测你的项目环境(JDK、Spring Boot、ORM、数据库、前端框架),记在
- 用
str == null ? null : str.trim().toLowerCase()统一预处理(注意:trim()不影响null,所以必须先判空) - 避免在每个
case里重复调用toLowerCase(),应在switch表达式中一次性完成 - 若业务要求保留大小写(如用户名),则需确保所有
case值与输入格式严格一致,并文档化说明
case 值必须是编译期常量
每个 case "xxx" 的字符串必须是字面量或 static final String,不能是运行时拼接的字符串(如 "a" + "b" 在某些上下文中可能不被视为常量):
立即学习“Java免费学习笔记(深入)”;
- 错误写法:
case someVariable:(编译失败) - 正确写法:
case "start":或case Constants.CMD_START:(其中Constants.CMD_START是public static final String) - 反编译可见,JVM 实际把字符串
switch编译为先查hashCode再逐个equals,所以非常量值无法参与该优化
性能与分支数量要匹配
字符串 switch 在分支较多(一般 ≥5)时,编译器会生成哈希跳转表,比长 if-else 链更快;但分支少时,两者性能差异极小,甚至 if-else 更轻量:
- 2–3 个分支:优先用
if-else,逻辑清晰、无 null 风险、调试直观 - 5 个以上固定字符串分支:用
switch更合适,尤其配合预处理后可稳定发挥哈希优势 - 避免在高频循环中对非标准化字符串反复做
toLowerCase().trim()再switch,可考虑提前归一化并缓存

















