---
title: "Modern Switch in Java"
slug: "modern-switch-in-java"
date: 2022-04-27T20:27:37Z
author: "Justin Biard"
tags:
  - "java"
description: "Whether we are learning to program in an object-oriented language (such as Java) or one where code executes logically from top to bottom, decisions need to be made about what happens next. We can call this branching."
draft: false
---

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

```java
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.

```java
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](https://docs.oracle.com/javase/specs/jls/se14/html/jls-14.html#jls-14.11) in Java.

```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)?

```java
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.

```shell
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](https://docs.oracle.com/javase/specs/jls/se14/html/jls-14.html#jls-14.11) 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.

```java
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.

```java
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.

```java
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:**
