Behavior of Switch Statements without fallthrough

Ethan McCue ethan at mccue.dev
Wed Jul 16 15:26:29 UTC 2025


I had a reader notice that the following code will not compile

https://javabook.mccue.dev/switch/exhaustiveness

enum Bird {
    TURKEY,
    EAGLE,
    WOODPECKER
}

boolean isScary(Bird bird) {
    switch (bird) {
        case TURKEY -> {
            return true;
        }
        case EAGLE -> {
            return true;
        }
        case WOODPECKER -> {
            return false;
        }
    }
}

void main() {}

I can rationalize this by imagining that, in the case of a switch
statement, there is no synthetic default inserted and thus it wouldn't be
friendly to a new enum variant. That's not a spec-centered interpretation,
but it would make sense to me.

What doesn't make sense is that adding a case null allows it to compile

enum Bird {
    TURKEY,
    EAGLE,
    WOODPECKER
}

boolean isScary(Bird bird) {
    switch (bird) {
        case TURKEY -> {
            return true;
        }
        case EAGLE -> {
            return true;
        }
        case WOODPECKER -> {
            return false;
        }
        case null -> {
            return true;
        }
    }
}

void main() {}

This was pointed out as potentially being the relevant part of the spec

https://docs.oracle.com/javase/specs/jls/se24/html/jls-14.html#jls-14.11.1.1


A set of case elements, P, covers a type T if one of the following cases
applies:
P covers a type U where T and U have the same erasure.
P contains a pattern that is unconditional for T.
T is a type variable with upper bound B and P covers B.
T is an intersection type T1& ... &Tn and P covers Ti, for one of the types
Ti (1≤ i ≤ n).
The type T is an enum class type E and P contains all of the names of the
enum constants of E.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://mail.openjdk.org/pipermail/amber-dev/attachments/20250716/6c4ce09d/attachment-0001.htm>


More information about the amber-dev mailing list