Java 17: warning "switch expression does not cover all possible input values" is not shown if there is no return
Asked Answered
B

1

7

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?

Brieta answered 9/2, 2023 at 9:5 Comment(4)
in your first example, nothing is returned for Type_D, in your second example, there is still a default value returnedAdjudication
what about using default, ex default -> Map.of();Winglet
first one is a switch expression (15.28. switch Expressions), second a switch statement (14.11. The switch Statement), and more explicitly: "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,"Weathered
( in other words, an expression must always return a value [or throw an Exception]; a statement can do nothing ) ( BTW some IDEs show a warning [configurable in Eclipse] for the second case )Weathered
B
10

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.

Brahms answered 9/2, 2023 at 9:25 Comment(2)
thank you! I just not 100% agree with A switch expression must be exhaustive (14.11.1.1), or a compile-time error occurs.. That is what I basically want. When I add a new type to the enum, I'd like to compiler warn me that I have to update the switch where this enum is used.Brieta
Less formal and shorter description in the Oracle's "Java Language Updates" article: Switch Expressions.Penrose

© 2022 - 2024 — McMap. All rights reserved.