Robert Lewis
Robert Lewis

Reputation: 1907

I'm prevented from using a switch statement that doesn't cover all possible cases

return degrees % 90 != 0? Optional.empty() : Optional.of( switch( degrees ) {
            case 0 -> NORTH;
            case 90 -> EAST;
            case 180 -> SOUTH;
            case 270 -> WEST;
            //default -> null;  is there something I can put here to make empty Optional?
        } );

Above returns an Optional containing an enum of the cardinal directions. The code has previously ensured that these are the only 4 possible values of degrees. But IntelliJ IDEA won't allow this, complaining that the switch hasn't handled all possible values. I've searched for a @SuppressWarnings annotation to allow this; the closest I've found is SwitchStatementWithoutDefaultBranch, but it doesn't help.

It seems like there should be an annotation that would allow this.

I know the code can be rewritten to work around the issue, but why can't this be handled?

Upvotes: 1

Views: 1651

Answers (2)

rzwitserloot
rzwitserloot

Reputation: 103018

There are two different switch constructs. The switch expression and the switch statement. The switch expression is quite new (added in JDK, um, 14? Less than 2 years ago). The switch statement form, on the other hand, is 25+ years old.

The switch statement form has had the property that many linting tools and IDEs will generate a warning if you aren't covering all the cases.

However, and this is the key, you are using the switch expression form, and compiler-provable exhaustiveness is REQUIRED by the java specification.

In other words, for switch statements, non-exhaustiveness is fine and not an error or even a javac-spec-enforced warning, but most linters/IDEs do warn for this, but you're using the switch expression form. The spec says that an error must be generated here. There is no @SuppressWarnings or any other intellij settings that you can set to make intellij ignore spec requirements.

The reason for this is simple: You are using this switch as an expression, so what should the compiler presume the switch resolves to if none of the case blocks is hit?

If you say: But that can't happen - well, the compiler does not know that and crazy things can occur. At best you would presume that the compiler will then throw something, but, well, the spec says that's not how it works.

Upvotes: 4

Sweeper
Sweeper

Reputation: 271820

You don't need a ternary operator here. Optional.ofNullable will give you an Optional.empty() if you pass in null, so you can do:

return Optional.ofNullable( switch( degrees ) {
            case 0 -> NORTH;
            case 90 -> EAST;
            case 180 -> SOUTH;
            case 270 -> WEST;
            default -> null;
        } );

Upvotes: 2

Related Questions