JDK 17:Switch 语句导致 java.lang.VerifyError:操作数堆栈上的类型错误

Zhe*_*dar 5 java switch-statement eclipse-jdt ecj java-17

刚刚在 Eclipse 2021-09 上尝试了 JDK17,结果失败并显示java.lang.VerifyError,这本身并没有多大帮助。我追踪到一个 switch 语句,该语句获取从一个Map或另一个泛型类型中提取的值。如果我在 switch 语句中使用局部变量,一切都会按预期工作。

测试代码:

import java.util.HashMap;
import java.util.Map;

public class SwitchFail {
  public static void main(String[] args) {
    //doesnt work
    Map<Integer, String> stringMap = new HashMap<>();
    stringMap.put(1, "Test");
    switch(stringMap.get(1)) {
    }

    //works
    String plainString = "Test";
     switch(plainString) {
    }
  }
}
Run Code Online (Sandbox Code Playgroud)

这会引发以下错误:

Error: Unable to initialize main class SwitchFail
Caused by: java.lang.VerifyError: Bad type on operand stack
Exception Details:
  Location:
    SwitchFail.main([Ljava/lang/String;)V @33: invokevirtual
  Reason:
    Type 'java/lang/Object' (current frame, stack[0]) is not assignable to 'java/lang/String'
  Current Frame:
    bci: @33
    flags: { }
    locals: { '[Ljava/lang/String;', 'java/util/HashMap', 'java/lang/Object' }
    stack: { 'java/lang/Object' }
  Bytecode:
    0000000: bb00 1059 b700 124c 2b04 b800 1312 19b9
    0000010: 001b 0300 572b 04b8 0013 b900 2102 0059
    0000020: 4db6 0025 57b1  

                   
            
Run Code Online (Sandbox Code Playgroud)

还没有尝试过 11 到 17 之间的其他 JDK。交换机在这些版本之间获得了一些新功能,所以可能就是这样。也许这是 Eclipse JDT 或我的本地 JDK 中的问题,因此尝试在其他配置或 IDE 上重现此错误会很好。尝试过适用于 macOS 的 OpenJDK(内部版本 17+35-2724)。

编辑: 也发生在

List<String> stringList = Arrays.asList("Test");
switch(stringList.get(0)) {}
Run Code Online (Sandbox Code Playgroud)

很可能是 Java 17 的新 JDT 或我的本地安装出现问题。

Zhe*_*dar 3

这确实是 Eclipse 的 JDT 中的一个错误。我可以确认在Bug 576093关闭后该问题已得到修复。有可用更新。