Java-17 - switch case - Unused method parameters should be removed

Viewed 603

I have a simple method which takes an enum and returns a String:

public static String enumToString(MyEnum type) {
    return switch (type) {
        case Enum1 -> "String_1";
        case Enum2 -> "String_2";
        case Enum3 -> "String_3";
        case Enum4 -> "String_4";
        case Enum5 -> "String_5";
        case Enum6 -> "String_6";
        default -> null;
    };
}

But Sonar gives me this Major error:Unused method parameters should be removed.

as you can see the parameter type is used in the switch. For more details when I use old switch case every thing is OK.

Any idea about the issue, does sonar cover new Java syntaxes?


Hmm, I notice that when I remove default -> null; sonar pass correctly! this is weird.

public static String enumToString(MyEnum type) {
    return switch (type) {
        case Enum1 -> "String_1";
        case Enum2 -> "String_2";
        case Enum3 -> "String_3";
        case Enum4 -> "String_4";
        case Enum5 -> "String_5";
        case Enum6 -> "String_6";
        //default -> null;
    };
}
2 Answers

This is not a bug, Sonar correctly evaluates that if the listing is exhaustive the switch-expression can never fall into the default branch.

On the other hand, if you decide to not list all possible enum constants, the default branch, however, must be declared. Otherwise, the code would not be compilable, because of the requirement that every enum constant can be matched.

Note: Your code contains a switch expression, not a switch statement.

Technically the syntax default -> null; is not a "parameter". The JLS refers to various components within a switch block as a "rule", "label", or "expression"; while the relevant JEP also uses the term "clause".

Regardless of what you call its components, Switch Expressions are distinct from the older Switch Statements. In particular, Switch Expressions are exhaustive.

From the JEP,

Exhaustiveness

The cases of a switch expression must be exhaustive; for all possible values there must be a matching switch label. (Obviously switch statements are not required to be exhaustive.)

In practice this normally means that a default clause is required; however, in the case of an enum switch expression that covers all known constants, a default clause is inserted by the compiler to indicate that the enum definition has changed between compile-time and runtime. Relying on this implicit default clause insertion makes for more robust code; now when code is recompiled, the compiler checks that all cases are explicitly handled. Had the developer inserted an explicit default clause (as is the case today) a possible error will have been hidden.

Sonar is smart enough to know when all of the bases are covered, making a default clause not only unreachable, but making it interfere with the behavior described above.

Related