为啥不完整的switch表达式编译成功
Posted
技术标签:
【中文标题】为啥不完整的switch表达式编译成功【英文标题】:Why does an incomplete switch expression compile successfully为什么不完整的switch表达式编译成功 【发布时间】:2019-04-22 04:56:47 【问题描述】:试用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.***.nullpointer.expression.SwitchExpressionMustComplete Caused by: java.lang.VerifyError: Bad local variable type Exception Details: Location: com/***/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/***/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;
替换评论可以解决它,但我的问题是:
第一季度。 为什么编译阶段同样成功?那不应该在编译时失败吗?
第二季度。我看到如此详细的错误消息的原因是什么? --enable-preview
功能会对此负责吗?
【问题讨论】:
【参考方案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
此程序不应编译,因为第一个案例正常完成。
【讨论】:
嗯,不知道这些是如何链接的,但相反,这个错误报告中的代码实际上无法为我编译并出现错误:or -> expected .... not a statement 问题的另一部分怎么样,我看到这么详细的错误信息是什么原因? (并不是我担心看到它,只是想知道我是否可以使用一些 JVM 标志来切换到此视图以报告错误。) @Naman 在这个答案的例子中,错误的情况是在一个返回值的情况之前,所以代码流到达后面的情况并执行它,错误地返回那个值。在您的问题示例中,错误的后面没有案例,因此它使局部变量未初始化。但显然,您的实际代码包含之后尝试使用该变量的尝试,并且具有将使用未初始化变量的代码路径会使字节码无效。所以代码被 JVM 的验证器拒绝,你看到的是带有 HotSpot 诊断的VerifyError
。
@Holger 实际上,我在 switch 表达式之后使用了变量,很高兴知道我得到这些详细日志的原因。感谢您分享详细信息。以上是关于为啥不完整的switch表达式编译成功的主要内容,如果未能解决你的问题,请参考以下文章
switch结构case语句后的多个语句必须放在花括号中。 这句话对吗?为啥?