Image Blog Switch Expressions in JDK 13
October 23, 2019

Using Switch Expressions in Java

Java Application Development

Switch Expressions, introduced under JEP 325 and refined under JEP 354, are an application of the classic Java switch statement in expression form – which allows developers to yield values. Switch statements, the precursor to Switch expressions, have been a part of Java since its inception.

Switch Statements

While switch statements have been with Java since day one, the decision to make them default their control flow to a fall through state makes them hard to troubleshoot. For example, if you forget to add a break; command to one of your blocks, then it and subsequent blocks will be executed until the next applicable break; . That’s not to mention the cumbersome code you get when trying to make Switch statements do things they weren’t designed to do.

The Introduction of Switch Expressions in JEP 325

Switch Expressions were first released in JEP 325 as a preview feature. The original intent was to simplify the switch process, as we talk about below. In the examples included on the JEP 325 release (below), they show one such simplification as the motivation for their work.


int numLetters;
switch (day) {
case MONDAY:
case FRIDAY:
case SUNDAY:
numLetters = 6;
break;
case TUESDAY:
numLetters = 7;
break;
case THURSDAY:
case SATURDAY:
numLetters = 8;
break;
case WEDNESDAY:
numLetters = 9;
break;
default:
throw new IllegalStateException("Wat: " + day);
}


The above code snippet shows a typical Switch statement trying to act as a switch expression. The code below shows it as a Switch expression (with the new -> shorthand.


int numLetters = switch (day) {
    case MONDAY, FRIDAY, SUNDAY -> 6;
    case TUESDAY                -> 7;
    case THURSDAY, SATURDAY     -> 8;
    case WEDNESDAY              -> 9;
};

 

Further Refinements of Switch Expressions in JEP 354

In JEP 354, OpenJDK developers outlined a few modifications to JEP 325, adding arrow labels and the yield() command.

Addition as Standard Feature for Java 14

After a successful preview stint in JEP 354, Switch Expressions were deemed ready for integration into the language in Java 14 with JEP 361.

You might be interested in:

Our COVID-19 Developer Impact Report looks at how development professionals and companies have been impacted by the COVID-19 epidemic, and the tactics they are using to stay productive and resilient.

Back to top

New Features in JEP 354 Switch Expressions

There are a few new features in JEP 354 with the introduction of Switch expressions, but the biggest change is centered around using Switch as an expression instead of a statement.

No Fall Through

Writing code using traditional Switch statements is great for low level code. But in higher level usage, it’s prone to error because of the break; command and fall through standard we outlined above. Because of the addition of Switch as an expression and the adoption of yield() as an expression-specific command, developers don’t have to include break; for each block, nor do they have to worry about finding the missing break; in long strings of blocks while debugging. That’s because when the case label is matched, it will trigger only the applicable line of code, not a fall through of the given block only halted by the break; command.

Arrow Labels

JEP 354 Switch Expressions also introduced the new arrow label -> . It can be used as shorthand following case L : labels in place of yield(). The caveat, as we’ll touch on in the next section, is that you can’t use yield() commands and the new shorthand -> together in the same block.

Back to top

Other Considerations With Java Switch Expressions

While there are a lot of benefits to using switch expressions in your Java applications, there are a few new things to consider.

Switch Expression Cases Must Be Exhaustive

Because switch is operating as an expression, it needs to be exhaustive. That means that for all possible values, you need to have a corresponding switch label. As shown below, you’ll see an inline complaint when you don’t account for an exception to the delineated cases.


static void calculate(int x, int y, Operation op) {
    int result = switch (op) {
    // ERROR! 'switch' expression does not cover all possible input values
      case ADD       -> x + y;
      case SUBTRACT  -> x - y;
      case DIVIDE    -> x / y;
      case MULTIPLY  -> x * y;
    };

    System.out.printf(OUTPUT, x, y, op.getSymbol(), result);
  }

  public enum Operation {
    ADD('+'),
    SUBTRACT('-'),
    DIVIDE('/'),
    MULTIPLY('*');

 

You Can’t Use yield() and -> in the Same Block

An additional consideration when dealing with MOD: commands in JDK Switch Expressions is the inability to mix and match yield() and the shorthand  -> . In the example below, we try to use MOD: to yield() x % y, but because we used the new arrow labels in the upper switch labels, we get the error, “Different case kinds used in the switch.”


static void calculate(int x, int y, Operation op) {
    int result = switch (op) {
      case ADD       -> x + y;
      case SUBTRACT  -> x - y;
      case DIVIDE    -> x / y;
      case MULTIPLY  -> x * y;
      case MOD: {
        System.out.println("MOD");
        yield x % y;
		// ERROR! different case kinds used in the switch
      }
    };

    System.out.printf(OUTPUT, x, y, op.getSymbol(), result);
  }

  public enum Operation {
    ADD('+'),
    SUBTRACT('-'),
    DIVIDE('/'),
    MULTIPLY('*'),
    MOD('%');


When we then standardize the normal cases to : yield, that error goes away.


static void calculate(int x, int y, Operation op) {
    int result = switch (op) {
      case ADD       : yield x + y;
      case SUBTRACT  : yield x - y;
      case DIVIDE    : yield x / y;
      case MULTIPLY  : yield x * y;
      case MOD: {
        System.out.println("MOD");
        yield x % y;
      }
    };

    System.out.printf(OUTPUT, x, y, op.getSymbol(), result);
  }

  public enum Operation {
    ADD('+'),
    SUBTRACT('-'),
    DIVIDE('/'),
    MULTIPLY('*'),
    MOD('%');

 

Control Statements Can’t Jump Through Switch Expressions

In this example shown in the JEP 354: Switch Expressions release, it shows that when trying to use yield(), the control statement continue triggers an “Illegal jump through a switch expression” error. That’s because switch is now handled as an expression, not a statement.


z: 
    for (int i = 0; i < MAX_VALUE; ++i) {
        int k = switch (e) { 
            case 0:  
                yield 1;
            case 1:
                yield 2;
            default: 
                continue z; 
                // ERROR! Illegal jump through a switch expression 
        };
    ...
    }

 

Back to top

Switch Expressions in Java | Final Thoughts

Switch expressions are a big quality of life improvement for coders using switch statements. Instead of trying to code Switch statements against the grain, they can now use these expressions to accomplish the same thing in a simpler (and easier to debug) way. 

Additional Resources

If you want information on the other JDK 13 preview feature, Text Blocks, I recently published an article that gives an overview of JEP 355: Text Blocks, as well as the introduction of new escape sequences in JEP 368. If you want to see my discussion of both Text Blocks and Switch Expressions, I recently hosted a webinar on the JDK 13 preview language features. I use some of the same examples we talk about in this and the above article.

If you want additional information on JEPs and how they impact Java, be sure to check out our webinar on JDK Enhancement Proposals, and our new resource hub, Exploring New Features in Java

If you're already looking forward to Java 14, be sure to check out my articles on JEP 359: Records preview language feature and JEP 370: Foreign-Memory Access API (Incubator).

Save Time on Development

Looking for ways to streamline your Java application development? See how much time you could save by skipping redeploys with JRebel. 

Try JRebel For Free

Back to top