Java 21 保护模式详尽性

Mar*_*tin 10 java pattern-matching java-21

我开始尝试新的Java 21功能模式匹配

public class Main {

  public static void main(String[] args) {

    RecordB recordB = new RecordB(true);

    switch(recordB) {
      case RecordB b when b.bool() -> System.out.println("It's true");
      case RecordB b when !b.bool() -> System.out.println("It's false");
    }

  }

  record RecordB(boolean bool) { }
}
Run Code Online (Sandbox Code Playgroud)

当编译上面的代码时,编译器会产生以下信息:the switch statement does not cover all possible input values

从我的角度来看,这不一定是真的。所以这是我的问题:任何受保护的模式是否总是使编译器的 switch 表达式不详尽,或者我在这里遗漏了一些东西?

lea*_*iro 12

任何受保护的模式是否总是使编译器的 switch 表达式不详尽,或者我在这里遗漏了一些东西?

不,并不是说“任何受保护的模式都会使 switch 语句变得不详尽”,而是必须至少有一个不受保护的模式覆盖该类型。如果不存在任何此类不受保护的模式,那么它就不是详尽的。

更正式地(参见JLS 14.11.1.1. 详尽的开关块),

如果满足以下情况之一,则switch表达式或语句的 switch 块switch对于选择器表达式来说是详尽的:e

  • 有一个default与开关块关联的标签。

  • 有一个case null, default与开关块关联的标签。

  • 包含与 switch 块关联的无保护标签(统称为元素)中出现的所有 case常量和case模式的集合 是非空的,并且涵盖选择器表达式的类型。casecasee

这里的关键点是非空

在您的情况下,包含出现在不受保护的案例标签中的案例模式的集合是空的


边注:

在实现模式、instanceof 和 switch 中的 JEP 455 基元类型后,如果使用嵌套模式bool直接访问值,则 switch 语句可能会很详尽(请参阅下面来自 davidalayachew 的评论)。

  • 这很棒。但最好编辑一下你的答案,并补充说这很快就会过时,因为他们刚刚宣布了原始模式的 JEP。这意味着您可以完全放弃防护,只使用嵌套模式,从而获得详尽性和简洁性。以下是原始模式 JEP 的链接 - https://mail.openjdk.org/pipermail/amber-dev/2023-September/008277.html (3认同)
  • 嘿@davidalayachew,感谢您的信息!我不确定是否应该编辑它,因为最初的问题没有使用嵌套模式......可能旁注可以。 (2认同)
  • @davidalayachew,感谢您在这里提出您的观点——我添加了一个旁注。如果您认为可以改进答案,请随时建议对答案进行任何编辑:) (2认同)