JDK 17: Switch statement causes java.lang.VerifyError: Bad type on operand stack
JDK 17: Switch statement causes java.lang.VerifyError: Bad type on operand stack
刚刚在 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) {
}
}
}
这会引发以下错误:
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
还没有在 11 到 17 之间尝试另一个 JDK。开关在这些版本之间获得了一些新功能,所以可能就是这样。
也许这是 Eclipse JDT 或我的本地 JDK 中的问题,因此任何尝试在另一个配置或 IDE 上重现此错误都会很棒。
尝试在 macOS 上使用 OpenJDK(内部版本 17+35-2724)。
编辑:
也发生在
List<String> stringList = Arrays.asList("Test");
switch(stringList.get(0)) {}
很可能是 Java 17 或我本地安装的新 JDT 的问题。
这是您的 Eclipse 的问题,而不是 Java-17 本身的问题。 Java-17 昨天才发布。等待一段时间,直到 IDE 更新为支持 Java-17.
演示:
import java.util.HashMap;
import java.util.Map;
public class SwitchFail {
public static void main(String[] args) {
Map<Integer, String> stringMap = new HashMap<>();
stringMap.put(1, "Test");
switch (stringMap.get(1)) {
default:
System.out.println("Hello");
}
String plainString = "Test";
switch (plainString) {
default:
System.out.println("Hi");
}
}
}
样本运行:
[~/Desktop]: java SwitchFail.java
Hello
Hi
用jar测试:
[~/Desktop/java17]: javac SwitchFail.java
[~/Desktop/java17]: jar -cvf java17test.jar .
added manifest
adding: SwitchFail.java(in = 379) (out= 212)(deflated 44%)
adding: SwitchFail.class(in = 920) (out= 546)(deflated 40%)
adding: .DS_Store(in = 6148) (out= 178)(deflated 97%)
[~/Desktop/java17]: java -cp java17test.jar SwitchFail
Hello
Hi
我系统上的JDK:
[~/Desktop/java17]: java -version
openjdk version "17" 2021-09-14
OpenJDK Runtime Environment (build 17+35-2724)
OpenJDK 64-Bit Server VM (build 17+35-2724, mixed mode, sharing)
这确实是 Eclipse 的 JDT 中的一个错误。我可以确认这是在 Bug 576093 关闭后修复的。有可用的更新。
刚刚在 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) {
}
}
}
这会引发以下错误:
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
还没有在 11 到 17 之间尝试另一个 JDK。开关在这些版本之间获得了一些新功能,所以可能就是这样。 也许这是 Eclipse JDT 或我的本地 JDK 中的问题,因此任何尝试在另一个配置或 IDE 上重现此错误都会很棒。 尝试在 macOS 上使用 OpenJDK(内部版本 17+35-2724)。
编辑: 也发生在
List<String> stringList = Arrays.asList("Test");
switch(stringList.get(0)) {}
很可能是 Java 17 或我本地安装的新 JDT 的问题。
这是您的 Eclipse 的问题,而不是 Java-17 本身的问题。 Java-17 昨天才发布。等待一段时间,直到 IDE 更新为支持 Java-17.
演示:
import java.util.HashMap;
import java.util.Map;
public class SwitchFail {
public static void main(String[] args) {
Map<Integer, String> stringMap = new HashMap<>();
stringMap.put(1, "Test");
switch (stringMap.get(1)) {
default:
System.out.println("Hello");
}
String plainString = "Test";
switch (plainString) {
default:
System.out.println("Hi");
}
}
}
样本运行:
[~/Desktop]: java SwitchFail.java
Hello
Hi
用jar测试:
[~/Desktop/java17]: javac SwitchFail.java
[~/Desktop/java17]: jar -cvf java17test.jar .
added manifest
adding: SwitchFail.java(in = 379) (out= 212)(deflated 44%)
adding: SwitchFail.class(in = 920) (out= 546)(deflated 40%)
adding: .DS_Store(in = 6148) (out= 178)(deflated 97%)
[~/Desktop/java17]: java -cp java17test.jar SwitchFail
Hello
Hi
我系统上的JDK:
[~/Desktop/java17]: java -version
openjdk version "17" 2021-09-14
OpenJDK Runtime Environment (build 17+35-2724)
OpenJDK 64-Bit Server VM (build 17+35-2724, mixed mode, sharing)
这确实是 Eclipse 的 JDT 中的一个错误。我可以确认这是在 Bug 576093 关闭后修复的。有可用的更新。