java 7+ switch(string)底层是编译器将字符串转换为hashcode()跳转表并配合equals()精确校验的双重机制;case必须为编译期常量,null直接抛npe,反编译可见switch(s.hashcode())嵌套if(s.equals("xxx"))结构。

Java 7 起支持 switch(String),但它不是 JVM 原生能力,而是编译器在编译期做的转换。底层不直接比对字符串内容,而是靠两步配合完成:先用 hashCode() 快速分流,再用 equals() 精确确认。
第一步:编译期算好哈希值,运行时只调一次
所有 case "xxx" 的字符串必须是编译期常量(比如字面量或 static final String)。编译器会在编译时就计算出每个 case 字符串的 hashCode(),并硬编码进 class 文件。运行时,只对传入的字符串调用一次 s.hashCode(),然后拿这个 int 值去跳转。
- 比如
"hello".hashCode()是 99162322,"world".hashCode()是 113318802,这些数字在 class 文件里已经写死 - 不会每个 case 都重新算一遍 hash,更不会在运行时动态拼接字符串来当 case
第二步:每个分支都加 equals() 校验,防哈希冲突
因为不同字符串可能有相同哈希值(例如 "Aa" 和 "BB" 的 hashCode 都是 2112),所以仅靠 hash 跳转不安全。编译器会在每个整数 case 分支里,插入对应的 if (s.equals("xxx")) 判断。
智能模型自动切换 V5.0.2 - 多模态感知,自动识别图片/视频/音频/代码/文本任务,切换最优模型。支持图片理解(qwen3-vl-plus)、视频音频(qwen3.5-plus)、代码(glm-5)、Office文档(MiniMax-M2.5)、推理等场景。零感知切换,无需手动操作。
- 如果 hash 匹配但
equals()不成立,就继续往下走(或落到 default) - 多个字符串 hash 相同时,它们会被编译到同一个 case 分支下,内部用 if-else 逐个 equals 区分
- null 会直接触发
NullPointerException,根本不会进入 switch 主体逻辑
底层跳转依赖 tableswitch 或 lookupswitch 指令
编译后生成的字节码,本质还是基于 int 的跳转表:
- case 值密集(比如 100、101、102 连续)→ 用
tableswitch,查表快 - case 值稀疏(比如 99162322、113318802、201234567)→ 用
lookupswitch,二分查找 - case 少于 3 个时,javac 可能干脆不生成跳转表,直接退化成 if-else 链
为什么必须是编译期常量?
因为编译器需要在编译阶段就确定每个 case 的哈希值,并固化进字节码。以下写法通不过编译:
-
String s = "abc"; case s:❌ 变量名不是常量 -
case new String("abc"):❌ new 出的对象不是编译期常量 -
case "a" + getSuffix():❌ 表达式含运行时方法调用 -
var s = "abc"; case s:❌var不产生常量










