Behavior of Switch Statements without fallthrough

Kenneth Fogel kfogel at dawsoncollege.qc.ca
Wed Jul 23 15:45:42 UTC 2025


To summarize, because there never was a switch expression it cannot be labelled as 'enhanced' while as there was the evil C-style switch we had to suffer with all these years, the new sensible switch is the enhanced switch. I do mean to be flippant. In the late 90s I worked with VB6. It had a Select Case that I felt made more sense that what C/C++ offered. I have been waiting since then for a switch at least as sensible as VB6. What we finally have is something superior to VB6, I think, its still early days.

Now for an absurd statement. Can we deprecate the C-style switch? I understand why it cannot be done, no need to think of me as delusional,  but can we at least send out an alert warning developers to avoid the old switch statement. If I was still in the classroom I'd teach the C-style switch like it was fire. Original fire can cook food but the enhanced fire we call a stove is much better.

Despite my poor attempts at humour, I do enjoy these discussions.

Ken

PS: I also never liked break. Not going to miss it.

PPS: Anyone who codes a return in a case block is a [insert insult here].

PPPS: Please get primitive pattern matching out of preview and into the fresh air


-----Original Message-----
From: amber-dev <amber-dev-retn at openjdk.org> On Behalf Of Cay Horstmann
Sent: July 22, 2025 1:08 PM
To: Liam Miller-Cushon <cushon at google.com>
Cc: amber-dev at openjdk.org
Subject: Re: Behavior of Switch Statements without fallthrough

Thank you, you are absolutely right. I re-read every mention of "enhanced" in the JLS, and have come to better appreciate the symmetry between "enhanced switch statements" and "switch expressions".

What is the preferred name for a non-enhanced switch statement? Basic switch statement (to mirror the basic for statement in the JLS)? Legacy switch statement? Asking for a friend who has to update a book...

Il 22/07/2025 17:46, Liam Miller-Cushon ha scritto:
> I think I'm mostly agreeing here, but note that the second example isn't an enhanced switch statement because it isn't a statement. 14.11.2 defines 'enhanced switch *statements*', the 'enhanced' concept doesn't apply to switch expressions.
>
> 15.28.1 defines additional rules for switch expressions and says they are required to be exhaustive and always get the MatchException.
>
>
>
> On Tue, Jul 22, 2025 at 8:32 AM Cay Horstmann <cay.horstmann at gmail.com <mailto:cay.horstmann at gmail.com>> wrote:
>
>     There is more to this.
>
>     Agreed that
>
>     boolean isScary(Bird bird) {
>           switch (bird) {
>               case TURKEY -> {
>                   return true;
>               }
>               case EAGLE -> {
>                   return true;
>              }
>              case WOODPECKER -> {
>                  return false;
>              }
>           }
>     }
>
>     is not an enhanced switch. But neither is
>
>     boolean isScary2(Bird bird) {
>           return switch (bird) {
>               case TURKEY -> true;
>               case EAGLE -> true;
>               case WOODPECKER -> false;
>           };
>     }
>
>     Yet the second method compiles.
>
>     There is another rule, §14.22 (https://docs.oracle.com/javase/specs/jls/se21/html/jls-14.html#jls-14.22 <https://docs.oracle.com/javase/specs/jls/se21/html/jls-14.html#jls-14.22>): ... a switch can complete normally if ... "The switch statement is not enhanced (§14.11.2) and its switch block does not contain a default label."
>
>     This rule applies only to switch statements, not to switch expressions.
>
>     IIRC, the thinking behind the treatment of switch statements in §14.22 was that the enum might change in a separate compilation unit. Then the switch simply completes without matching any cases. In contrast, for switch expressions (and enhanced switch statements), a MatchException is thrown in that situation.
>
>     In summary, here is what happens when no case applies to the selector:
>
>                     statement   expression
>     not enhanced  completes   throws ME
>     enhanced      throws ME   throws ME
>
>     As it says in JEP 361: The greater the divergence between switch expressions and switch statements, the more complex the language is to learn, and the more sharp edges there are for developers to cut themselves on.
>
>     Cheers,
>
>     Cay
>
>     Il 16/07/2025 17:49, Liam Miller-Cushon ha scritto:
>      > I think JLS 14.11.2 covers this:
>      >
>      >  > An enhanced switch statement is one where ... there is a case ... null
>      > ...
>      >  > For compatibility reasons, switch statements that are not enhanced switch statements are not required to be exhaustive.
>      >
>      > 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.
>      >
>      > https://bugs.openjdk.org/browse/JDK-8345997 <https://bugs.openjdk.org/browse/JDK-8345997> <https://bugs.openjdk.org/browse/JDK-8345997 <https://bugs.openjdk.org/browse/JDK-8345997>> and https://mail.openjdk.org/pipermail/amber-dev/2024-December/009139.html <https://mail.openjdk.org/pipermail/amber-dev/2024-December/009139.html> <https://mail.openjdk.org/pipermail/amber-dev/2024-December/009139.html <https://mail.openjdk.org/pipermail/amber-dev/2024-December/009139.html>> cover similar ground.
>      >
>      > On Wed, Jul 16, 2025 at 8:26 AM Ethan McCue <ethan at mccue.dev <mailto:ethan at mccue.dev> <mailto:ethan at mccue.dev <mailto:ethan at mccue.dev>>> wrote:
>      >
>      >     I had a reader notice that the following code will not compile
>      >
>      > https://javabook.mccue.dev/switch/exhaustiveness <https://javabook.mccue.dev/switch/exhaustiveness> <https://javabook.mccue.dev/switch/exhaustiveness <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 <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 <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.
>      >
>      >
>
>     --
>
>     Cay S. Horstmann | https://horstmann.com/ <https://horstmann.com/>
>

--

Cay S. Horstmann | https://horstmann.com/



More information about the amber-dev mailing list