javapattern-matchingjava-21

Java 21 guarded pattern exhaustiveness


I started to play with the new Java 21 feature - pattern matching.

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) { }
}

When compiling the code above, the compiler yields information that the switch statement does not cover all possible input values

This is not necessarily true from my perspective. So here is my question: does any guarded pattern always make the switch expression non-exhaustive for the compiler or I am missing something here?


Solution

  • does any guarded pattern always make the switch expression non-exhaustive for the compiler or I am missing something here?

    No, it's not that "any guarded pattern makes the switch statement non-exhaustive", but there must be at least one unguarded pattern covering the type. If there is not any such unguarded pattern, it makes it non-exhaustive.

    More formally (see JLS 14.11.1.1. Exhaustive Switch Blocks),

    The switch block of a switch expression or switch statement is exhaustive for a selector expression e if one of the following cases applies:

    • There is a default label associated with the switch block.

    • There is a case null, default label associated with the switch block.

    • The set containing all the case constants and case patterns appearing in an unguarded case label (collectively known as case elements) associated with the switch block is non-empty and covers the type of the selector expression e.

    The key point here is non-empty.

    In your case the set containing the case patterns appearing in an unguarded case label is empty.


    Side note:

    After JEP 455 Primitive types in Patterns, instanceof, and switch is implemented, the switch statement could be exhaustive if a nested pattern is used to access bool value directly (see comments below from davidalayachew).