When branching based on the truth-value of some expression, an if-condition-statement to make such decisions is a good choice.
This means if "finished" equals true, do A. Otherwise, do B, by default.
But what happens if we have more than two choices? The Java language can handle any number of possible outcomes with more complex condition blocks.
We can also make decisions using a switch statement. Many of Java's basic language features were originally geared towards easing the transition for C programmers. Let's rewrite the above code using a C-style switch in Java.
In this example, the switch is intended to behave the same and the choice between an if-else block and a switch is purely the programmer's preference. The switch is less repetitive and visually easier on the eyes in my opinion but it also comes with some new potential pitfalls and a new keyword (break.)
Switch, unlike the if-else block, uses a break to signal the end of a group of statements that follow each case label. So what happens if I omit break from my case on accident (or on purpose)?
Unlike an if-else block, the C-style switch statement includes a behavior known as "fall-through." What this means is that we could have unintended consequences at the cost of more readable syntax.
This default behavior of "falling through" switch cases until a break is found, however unfortunate, or sometimes useful, comes from Java's original design. The good news is that in modern Java we have new tools that offer the benefits of the switch block but without the break -or- the fall-through behavior.
Java 14+ enhances the classic form of switch differentiated as expressions or statements, with and without fall-through. (You can read more about this in the Java Language Specification or see the highlights below.)
- Assigning the result of a switch block to a variable? (its an expression)
- Using the switch to branch without yielding a value? (its a statement)
- Using case ... : (it will fall through)
- Using case ... -> (it will not fall through)
All of the switch examples above are switch statements with fall-through. Here is an example of a switch statement without fall-through.
And here is an example of the new switch expression syntax that yields a String literal directly to a variable. This is a nice, clean syntax for this specific use case.
It's worth mentioning that you can still use a non-fall-through syntax to execute groups of statements. To achieve this you need to wrap your statements in a block with curly braces, and if using an expression, call yield with a value.
That covers the three main examples of switch in modern Java. There is one final form of using switch as an expression with fall-through but I won't cover it here. It essentially involves combining the fall-through syntax with each case requiring a final yield "value" statement.
Everything is (or perhaps was at one point) useful to somebody but I think the main takeaway with the switch updates in Java is to prefer the non-fall-through syntax unless you absolutely need C-style fall-through. In which case, you should investigate compile-time flags for fall-through safety and annotate your switch. This will make it extra clear for your future self and colleagues that the block is working as designed (versus missing a break in error.)
Thank you for following along. Writing helps to reinforce what I am learning and I hope you find this style of writing helpful. If you find any errors or mistakes feel free to ping me.
Cheers!
Supplemental references: