Почему неполное выражение переключения успешно компилируется

Пробуем JDK / 12 EarlyAccess Build 20, где JEP-325 Switch Expressions интегрирован в качестве предварительной версии. Пример кода для выражений (как и в JEP):

Scanner scanner = new Scanner(System.in);
Day day = Day.valueOf(scanner.next().toUpperCase());
int i = switch (day) {
    case MONDAY,TUESDAY, WEDNESDAY:
        break 0;
    default:
        System.out.println("Second half of the week");
        // ERROR! Group doesn't contain a break with value
};

Я пытался выполнить ту же процедуру, что и в предыдущем вопросе о том, как Скомпилировать функцию предварительного просмотра JDK12 с Maven и выполните указанный выше блок кода с помощью командной строки:

java --enable-preview -jar target/jdk12-updates-1.0.0-SNAPSHOT.jar

Как и ожидалось, я получил следующую ошибку:

Error: Unable to initialize main class
com.stackoverflow.nullpointer.expression.SwitchExpressionMustComplete
Caused by: java.lang.VerifyError: Bad local variable type Exception
Details:   Location:
    com/stackoverflow/nullpointer/expression/SwitchExpressionMustComplete.main([Ljava/lang/String;)V @66: iload   
Reason:
    Type top (current frame, locals[4]) is not assignable to integer   
Current Frame:
    bci: @66
    flags: { }
    locals: { '[Ljava/lang/String;', 'java/util/Scanner', 'com/stackoverflow/nullpointer/Day' }
    stack: { }   
Bytecode:
    0000000: bb00 0259 b200 03b7 0004 4c2b b600 05b8
    0000010: 0006 4db2 0007 2cb6 0008 2eaa 0000 001f
    0000020: 0000 0001 0000 0003 0000 0019 0000 0019
    0000030: 0000 0019 0336 04a7 000b b200 0912 0ab6
    0000040: 000b 1504 3eb1                        
Stackmap Table:
    append_frame(@52,Object[#2],Object[#34])
    same_frame(@58)
    same_frame(@66)

Мне известно, что в документе указывается, что код ошибочный, и замена комментария на break 1; решает его, но у меня есть следующие вопросы:

Q1. Почему на этапе компиляции происходит то же самое? Разве это не должно произойти во время самой компиляции?

Q2. В чем причина такого подробного сообщения об ошибке? Может ли за это отвечать функция --enable-preview?


person Naman    schedule 19.11.2018    source источник


Ответы (1)


Это известная ошибка. См. JDK-8212982 для получения подробной информации о его статусе.

Этот код:

public class SwitchBug { 

    static String hold(String item) { 
        return switch(item) { 
            case String s -> { System.out.println(s); } 
            default -> "temp"; 
        }; 
    } 

    public static void main(String[] args) { 
        System.out.println(hold("bug")); 
    } 
}

компилирует и производит:

bug 
temp 

Эта программа не должна компилироваться, поскольку первый случай завершается нормально.

person Brian Goetz    schedule 19.11.2018
comment
Ну, не знаю, как они связаны, но, напротив, код в этом отчете об ошибке действительно не компилируется для меня с ошибкой: или - ›ожидалось .... не утверждение - person Naman; 20.11.2018
comment
Как насчет другой части вопроса, в чем причина того, что я вижу такое подробное сообщение об ошибке? (Не то чтобы я беспокоился об этом, просто интересно узнать, могу ли я использовать какой-нибудь флаг JVM, чтобы переключиться на это представление для сообщений об ошибках.) - person Naman; 20.11.2018
comment
@Naman в примере этого ответа ошибочный случай находится перед случаем возврата значения, поэтому поток кода достигает следующего случая и выполняет его, ошибочно возвращая это значение. В примере вашего вопроса за ошибочным нет случая, поэтому он оставляет локальную переменную неинициализированной. Но, по-видимому, ваш фактический код содержал попытку использовать эту переменную впоследствии, и наличие пути кода, в котором использовалась бы неинициализированная переменная, делает байт-код недействительным. Таким образом, код отклоняется верификатором JVM, и вы видите VerifyError с диагностикой HotSpot. - person Holger; 10.05.2019
comment
@Holger Действительно, я использовал переменную после выражения switch, и хорошо знать причину, по которой я получил эти подробные журналы. Спасибо, что поделились подробностями. - person Naman; 11.05.2019