<div dir="ltr">I think JLS 14.11.2 covers this:<br><br>> An enhanced switch statement is one where ... there is a case ... null<br>...<br>> For compatibility reasons, switch statements that are not enhanced switch statements are not required to be exhaustive.<br><br>The first example without the 'case null' isn't an 'enhanced' switch, so it isn't required to be exhaustive, so it doesn't get the synthetic default that throws a MatchException.<br><br><a href="https://bugs.openjdk.org/browse/JDK-8345997">https://bugs.openjdk.org/browse/JDK-8345997</a> and <a href="https://mail.openjdk.org/pipermail/amber-dev/2024-December/009139.html">https://mail.openjdk.org/pipermail/amber-dev/2024-December/009139.html</a> cover similar ground.</div><br><div class="gmail_quote gmail_quote_container"><div dir="ltr" class="gmail_attr">On Wed, Jul 16, 2025 at 8:26 AM Ethan McCue <<a href="mailto:ethan@mccue.dev">ethan@mccue.dev</a>> wrote:<br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><div dir="ltr">I had a reader notice that the following code will not compile<br><br><a href="https://javabook.mccue.dev/switch/exhaustiveness" target="_blank">https://javabook.mccue.dev/switch/exhaustiveness</a><br><br><font face="monospace">enum Bird {</font><br><font face="monospace"> TURKEY,</font><br><font face="monospace"> EAGLE,</font><br><font face="monospace"> WOODPECKER</font><br><font face="monospace">}</font><br><br><font face="monospace">boolean isScary(Bird bird) {</font><br><font face="monospace"> switch (bird) {</font><br><font face="monospace"> case TURKEY -> {</font><br><font face="monospace"> return true;</font><br><font face="monospace"> }</font><br><font face="monospace"> case EAGLE -> {</font><br><font face="monospace"> return true;</font><br><font face="monospace"> }</font><br><font face="monospace"> case WOODPECKER -> {</font><br><font face="monospace"> return false;</font><br><font face="monospace"> }</font><br><font face="monospace"> }</font><br><font face="monospace">}</font><br><br><font face="monospace">void main() {}</font><br><br><font face="arial, sans-serif">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.<br><br>What doesn't make sense is that adding a case null allows it to compile<br><br></font><font face="monospace">enum Bird {</font><br><font face="monospace"> TURKEY,</font><br><font face="monospace"> EAGLE,</font><br><font face="monospace"> WOODPECKER</font><br><font face="monospace">}</font><br><br><font face="monospace">boolean isScary(Bird bird) {</font><br><font face="monospace"> switch (bird) {</font><br><font face="monospace"> case TURKEY -> {</font><br><font face="monospace"> return true;</font><br><font face="monospace"> }</font><br><font face="monospace"> case EAGLE -> {</font><br><font face="monospace"> return true;</font><br><font face="monospace"> }</font><br><font face="monospace"> case WOODPECKER -> {</font><br><font face="monospace"> return false;</font><br><font face="monospace"> }</font><br><font face="monospace"> case null -> {</font><br><font face="monospace"> return true;</font><br><font face="monospace"> }</font><br><font face="monospace"> }</font><br><font face="monospace">}</font><br><br><font face="monospace">void main() {}</font><br><br><font face="arial, sans-serif">This was pointed out as potentially being the relevant part of the spec</font><br><br><a href="https://docs.oracle.com/javase/specs/jls/se24/html/jls-14.html#jls-14.11.1.1" target="_blank">https://docs.oracle.com/javase/specs/jls/se24/html/jls-14.html#jls-14.11.1.1</a><br><br><br><font face="monospace">A set of case elements, P, covers a type T if one of the following cases applies:<br>P covers a type U where T and U have the same erasure.<br>P contains a pattern that is unconditional for T.<br>T is a type variable with upper bound B and P covers B.<br>T is an intersection type T1& ... &Tn and P covers Ti, for one of the types Ti (1≤ i ≤ n).<br>The type T is an enum class type E and P contains all of the names of the enum constants of E.<br><br><br></font><font face="arial, sans-serif"></font></div>
</blockquote></div>