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