Ошибка проверки Java 14 из безобидного оператора

#java #switch-statement #verifyerror #java-14

#java #оператор переключения #ошибка проверки #java-14

Вопрос:

При попытке запустить следующий сегмент кода (после его успешной компиляции) из eclipse 2020-06 (с использованием jdk-14.0.1):

 import java.util.*;
public class VerifyErrorTesting {
    public static void main(String[] args) {
        new ArrayList<Double>().add(
            switch("t") {
            case "t" -> Double.valueOf(0);
            default -> 1d;
            }
        );
    }
}
  

Я получаю следующее VerifyError :

 Error: Unable to initialize main class othergoofs.VerifyErrorTesting in module goofer
Caused by: java.lang.VerifyError: Instruction type does not match stack map
Exception Details:
  Location:
    othergoofs/VerifyErrorTesting.main([Ljava/lang/String;)V @58: invokevirtual
  Reason:
    Current frame's stack size doesn't match stackmap.
  Current Frame:
    bci: @58
    flags: { }
    locals: { '[Ljava/lang/String;', 'java/lang/String' }
    stack: { 'java/util/ArrayList', 'java/lang/Double' }
  Stackmap Frame:
    bci: @58
    flags: { }
    locals: { '[Ljava/lang/String;' }
    stack: { 'java/util/ArrayList', double, double_2nd }
  Bytecode:
    0000000: bb00 1059 b700 1212 1359 4cb6 0015 ab00
    0000010: 0000 0028 0000 0001 0000 0074 0000 0012
    0000020: 2b12 13b6 001b 9a00 06a7 000d 0eb8 001f
    0000030: b600 25a7 0007 0fb8 001f b600 2957 b1  
  Stackmap Table:
    full_frame(@32,{Object[#47],Object[#22]},{Object[#16]})
    same_locals_1_stack_item_frame(@44,Object[#16])
    same_locals_1_stack_item_frame(@54,Object[#16])
    full_frame(@58,{Object[#47]},{Object[#16],Double})
  

Я попытался скомпилировать тот же код с помощью javac, и он работает без проблем; ошибка возникает только при запуске из eclipse. Когда я даже слегка изменяю код, ошибка исчезает. Например, изменение Double.valueOf(0) на 0d выполняется без ошибок. Изменение 1d на Double.valueOf(1) также выполняется без ошибок. Замена new ArrayList<Double>().add на Double d= или double d= также выполняется нормально.

Мой вопрос: что является причиной VerifyError ?

Комментарии:

1. Вероятно: компилятор eclipse создает недопустимый байтовый код. Я думаю, что это скорее указывает на дефект в системе отслеживания проблем компилятора eclipse.

2. Переключатель должен сбалансировать типы Double и double до одного и того же типа. Ожидаемое значение Double, но, похоже, это не играет роли. Вы могли бы проверить (не-) блокировку, выполненную в байтовом коде.