<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">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">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>