I'm developing with Java 17 in IntelliJ IDEA 2022.2.
In some cases 'switch' expression does not cover all possible input values
is shown, but in some not. I'd like to figure out why.
Let's assume that entityType
is an enum with 3 values and I'm adding 4th one TYPE_D
. So I expect to see 'switch' expression does not cover all possible input values
errors where I use this enum in switch
.
When it is shown:
public Map<String, String> getRecordDetails() {
return switch (entityType) {
case TYPE_A -> Map.of("A","A");
case TYPE_B -> Map.of("B","B");
case TYPE_C -> Map.of("C","C");
};
}
When it's not shown:
public String getRecordDetails() {
StringBuilder stringBuilder = new StringBuilder();
switch (entityType) {
case TYPE_A -> stringBuilder.append("A");
case TYPE_B -> stringBuilder.append("B");
case TYPE_C -> stringBuilder.append("C");
};
return stringBuilder.toString();
}
I see it is related when I do return of switch
case, but why it is not shown when I have switch case inside of function's code?
When you use a switch
as part of a return
, it is a switch expression. But if you just put the switch
randomly in the middle of a method, it is parsed as a switch statement. These have different rules. Importantly, switch expressions need to be exhaustive.
From the Java Language Specification:
If the type of the selector expression is not an enum type, then there is exactly one default label associated with the switch block.
If the type of the selector expression is an enum type, then (i) the set of the case constants associated with the switch block includes every enum constant of the enum type, and (ii) at most one default label is associated with the switch block.
On the other hand, switch statements do not have this restriction.
Intuitively, expressions have to evaluate to a value, but statements don't have to. Therefore, switch expressions have to cover all cases. If they don't, then there will be situations where it can't evaluate to anything.
In the preview specifications of later versions of Java, the idea of an "exhaustive switch" is more clearly defined, because they now need to support pattern matching among other things.
The switch block of a switch expression or switch statement is exhaustive for a selector expression of type T if either (i) the switch block contains a default switch label, or (ii) the set containing all the unguarded case elements supported by switch labels in the switch block is exhaustive for T, which is specified as follows: [...]
And later,
A switch expression must be exhaustive (14.11.1.1), or a compile-time error occurs.