What changed in Java 12

Switch expressions previewed

Small, and notable for beginning the pattern-matching work that ran through to 21 — switch becoming an expression was the first step.

Released 2019-03 · 1 features · 3 questions · 1 scenarios

Features

Switch expressions (preview)

previewJEP 325

switch can yield a value, use arrow labels with no fall-through, and be checked for exhaustiveness. Previewed in 12 and 13, standard in 14.

The problem it solved

The statement form fell through by default, could not produce a value, and required a mutable variable assigned in every branch.

How you did it before

Declaring a variable before the switch and assigning it in each case, with break statements guarding against accidental fall-through.

Compiled and run on this build
int day = 3;
String name = switch (day) {
    case 1, 7 -> "weekend";
    case 2, 3, 4, 5, 6 -> "weekday";
    default -> "unknown";
};
System.out.println(name);

// The old form, for comparison — note the mutable variable.
String old;
switch (day) {
    case 1:
    case 7:  old = "weekend"; break;
    default: old = "weekday";
}
System.out.println(old);
Output
weekday
weekday

Journey: Preview in 12 (JEP 325) and 13 (JEP 354), standard in 14 (JEP 361).

Asked as

  • What is the difference between a switch statement and a switch expression?
  • What does yield do, and when do you need it?
  • When does the compiler require a default branch?

Scenario question

  • A code review turns up a 40-line switch statement assigning to a mutable local, with one case missing a break.

    What do you change, and what does it buy you?

    What a good answer weighs

    Convert it to a switch expression with arrow labels: no fall-through is possible, the variable becomes final, and if the subject is an enum or sealed type the compiler checks exhaustiveness. The missing break stops being a class of bug rather than a bug that was fixed.

    Other versions