为什么不完整的开关表达式可以成功编译

时间:2018-11-19 19:22:37

标签: java javac java-12 preview-feature switch-expression

尝试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
};

我试图遵循与上一个问题有关的相同步骤,如何使用命令行Compile a JDK12 preview feature with 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功能是否应对此负责?

1 个答案:

答案 0 :(得分:11)

这是一个已知的错误。参见JDK-8212982  详细了解其状态。

  

此代码:

<xsl:param name="ids-to-delete" select="unparsed-text-lines('List_Of_Ids.txt')"/>
     

编译并产生:

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

该程序不应编译,因为第一种情况正常完成。