Java 21 pattern matching false positives

  • ALM used: GitHub
  • CI system used: GHA
  • Languages used: Java 21

With the following code:

sealed interface Animal permits Cat, Dog {}
record Cat() implements Animal { }
record Dog() implements Animal { }

public static int getLives(Animal animal) {
    return switch (animal) {
        case Cat ignored -> 7;
        case Dog ignored -> 1;

SonarCloud will complain that:

  1. java:S131 Add a default case for this switch. Thanks to sealed interfaces this pattern match is exhaustive and enforced by the compiler, so no default case is required.
  2. java:S1481 Remove this unused “ignored” local variable. It cannot be removed (unless using Java 21 preview, in which case it could be replaced by an underscore).
  3. java:S1301 Replace this “switch” statement by “if” statements to increase readability. With a switch over a sealed interface we gain exhaustive matching, which can be preferable over ifs.

Also, this is not shown in the example above, but if we had a case statement with an empty body (e.g. case Something something -> { }, SonarCloud would complain that:

  1. java:S108 Either remove or fill this block of code. With exhaustive pattern matching it is not possible to remove this case statement - and filling the block of code depends on the use case.
1 Like

Hey there.

I’ve moved your post to the section on reporting false-positives. Can you update your post with the specific Rule IDs concerned? Thanks!

Hi Colin, updated my original post. Thank you!

Thanks! One ticket already exists.


I’ll refer the other cases to our team of experts. Stay tuned!

Hey @kyris ,

Thanks a lot for the feedback, it is spot on as we are working these days on improving our support of Java 21. I created multiple tickets thanks to you. Thanks, @Colin, for identifying the first one as well!

Here are the tickets and comments related to what you reported:

  • java:S108: Either remove or fill this block of code

    • As mentioned in its description, this rule will not raise issues if there is a comment inside the empty block. We believe that empty blocks should contain a comment explaining why there are no instructions in this case, and I feel it’s also valuable for switch statements, even when switching over sealed classes. I would therefore not consider this as an FP. Taking your sealed class example, this would be valid:
    public static void petAnimal(Animal animal) {
      switch (animal) {
        case Cat maurice -> { /* cats are cats and do not accept to be pet */ }
        case Dog doug ->;
  • java:S131: “switch” statements should have “default” clauses

    • SONARJAVA-4908 - FP on S131 when using switch statement on sealed classes
  • java:S1481: Unused local variables should be removed

    • SONARJAVA-4907 - FP on S1481 when using type pattern matching in case clauses of a switch
  • java:S1301: “switch” statements should have at least 3 “case” clauses

    • SONARJAVA-4441 - FP on S1301 [Java 14+] for switch statements with a case containing multiple labels (known issue)
    • SONARJAVA-4461 - FP on S1301 for small switch cases with new syntax -> (known issue)
    • SONARJAVA-4904 - FP on S1301 when using switch statement with type patterns (new issue)


Thank you Michael, wasn’t aware about the comment thing in S108!

This topic was automatically closed 7 days after the last reply. New replies are no longer allowed.