Modern Switch in Java

When branching based on the truth-value of some expression, an if-condition-statement to make such decisions is a good choice.

boolean finished = true; // possibly true or false check
if (finished) {
    System.out.println("The answer is 42.");
} else {
    System.out.println("What is the ultimate answer?");
}
Example of a simple if-else block.

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.

String favoriteColor = "red"; // scan for some user input

if (favoriteColor.equals("red")) {
    // do something red.
} else if (favoriteColor.equals("green")) {
    // do something green.
} else if (favoriteColor.equals("etc...")) {
    // do something etc...
} else {
    // ... what happens by default?
}
Example of a more complex if-else block

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.

String favoriteColor = "red"; // scan for some user input

switch (favoriteColor) {
    case "red":
        // do something red.
        break;
    case "green":
        // do something green.
        break;
    case "etc...":
        // do something etc...
        break;
    default:
        // ... what happens by default?
}
C-style switch block written 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)?

String favoriteColor = "red"; // scan for some user input

switch (favoriteColor) {
    case "red":
        System.out.println("Go red team!");
        // oops
    case "blue":
        System.out.println("Go blue team!");
        // oops again, I forgot to break;
    case "etc...":
        System.out.println("Well, this is awkward...");
        break;
    default:
        System.out.println("Go team!");
}
Switch with some programmer errors. (missing breaks)

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.

Go red team!
Go blue team!
Well, this is awkward...
The good (or bad?) effects of fall-through are demonstrated.

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.

var dice = new Random();
var roll = dice.nextInt(1, 7);
String actionItem = "";

switch (roll) {
    case 1 -> 
        actionItem = "launch rocket";
    case 2 -> 
        actionItem = "make car";
    case 3 -> 
        actionItem = "dig tunnel";
    default -> 
        actionItem = "time for memes";
};

System.out.println(actionItem);
Example of a Java 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.

var dice = new Random();
var roll = dice.nextInt(1, 7);

String actionItem = switch (roll) {
    case 1 -> "launch rocket";
    case 2 -> "make car";
    case 3 -> "dig tunnel";
    default -> "time for memes";
};

System.out.println(actionItem);
Example of Java switch expression. (without fall-through)

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.

var dice = new Random();
var roll = dice.nextInt(1, 7);

String actionItem = switch (roll) {
    case 1 -> 
        {
            // prepare rocket fuel...
            // do science stuff...
            yield "launch rocket"; // yield required because of group
        }
    case 2 -> "make car";
    case 3 -> "dig tunnel";
    default -> "time for memes";
};

System.out.println(actionItem);
Example of Java switch expression with a group of statements. (without fall-through)

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:

JEP 361: Switch Expressions
Chapter 14. Blocks and Statements