Java 1.8中switch结合泛型返回值触发Bad type on operand stack是否为bug
这是Oracle JDK/OpenJDK 8u311及更早版本的已知原生编译器Bug,由Javac编译带泛型返回值的switch表达式时字节码生成逻辑错误导致。
根因说明
Objects.requireNonNull是泛型方法,理论上会返回和入参类型完全一致的结果,你传入的是String类型,返回值也应当是String。但受Bug影响,Javac编译时没有正确处理泛型推导的结果,直接将requireNonNull的返回值按照原始上界Object类型存储到局部变量。而字符串switch底层需要先调用表达式的hashCode方法,此时操作数栈顶是Object类型,无法直接调用String的方法,就触发了类加载阶段的字节码校验错误,和你贴的错误栈里Type 'java/lang/Object' is not assignable to 'java/lang/String'的描述完全吻合。
修复与规避方案
该Bug在JDK 8u321及更高的8版本,以及JDK 9+所有版本中已经被修复,升级对应JDK版本即可解决问题。
如果暂时无法升级JDK,可以通过以下任意一种方式修改代码规避:
- 先将
Objects.requireNonNull的结果显式赋值给String变量,再传入switch语句:
String nonNullTest = Objects.requireNonNull(test); switch (nonNullTest) { // 原有case逻辑不变 }
- 为
requireNonNull泛型方法显式指定类型参数:
switch (Objects.<String>requireNonNull(test)) { // 原有case逻辑不变 }
- 替换为提前手动判空逻辑,不把泛型方法调用直接作为switch的表达式。
内容的提问来源于stack exchange,提问作者fls-indinf
相关产品推荐
相关产品推荐

