简体   繁体   中英

JDK 17: Switch statement causes java.lang.VerifyError: Bad type on operand stack

Just tried JDK17 on Eclipse 2021-09 to have it fail with a java.lang.VerifyError , which wasn't very helpful itself. I tracked it down to a switch statement, that gets fed a value pulled out of a Map or another generic type. If I use a local variable in the switch statement instead, everything works as intended.

Test code:

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) {
    }
  }
}

This throws the following error:

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  

                   
            

Didn't try another JDK between 11 and 17 yet. Switches gained some new functions between those versions, so that might be it. Maybe it's a problem in the Eclipse JDT or my local JDK, so any tries to reproduce this error on another configuration or IDE would be great. Tried on OpenJDK (build 17+35-2724) for macOS.

Edit: Also happens on

List<String> stringList = Arrays.asList("Test");
switch(stringList.get(0)) {}

Most likely an issue with the new JDT for Java 17 or my local installation.

It is a problem with your Eclipse, not with Java-17 itself. Java-17 has been released only yesterday. Wait for some time until the IDEs are updated to support Java-17.

Demo:

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");
        }
    }
}

A sample run:

[~/Desktop]: java SwitchFail.java
Hello
Hi

Test with 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

The JDK on my system:

[~/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)

This was indeed a bug in Eclipse's JDT. I can confirm this was fixed after Bug 576093 was closed. There is an update available.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM