W3docs

Java Switch Expressions

Modern switch expressions in Java with arrow syntax, yield, and exhaustive pattern matching.

Java 14 promoted switch expressions to a standard language feature. They build on the traditional switch statement with three big improvements: they produce a value, they use a cleaner arrow syntax, and they make fall-through impossible. If you're on Java 14 or newer, prefer them.

Arrow-form syntax

String day = "TUE";

String label = switch (day) {
  case "MON", "TUE", "WED", "THU", "FRI" -> "weekday";
  case "SAT", "SUN" -> "weekend";
  default -> "unknown";
};

Three things to notice:

  1. The whole switch is an expression — it evaluates to a value you can assign (note the trailing ;).
  2. Each case uses -> instead of :. The right-hand side is one statement or expression.
  3. Multiple labels are allowed in one case, comma-separated. No break, no fall-through.

Block bodies with yield

If a case needs multiple statements, use a block — and inside the block, return the value with yield:

int score = 78;

String grade = switch (score / 10) {
  case 10, 9 -> "A";
  case 8 -> "B";
  case 7 -> {
    System.out.println("close to B");
    yield "C";
  }
  case 6 -> "D";
  default -> "F";
};

yield is like return, but for the switch expression — it sets the value of this switch and exits the case. (Don't confuse it with return, which would exit the enclosing method.)

Statements still work

You can use arrow syntax for side effects too, in which case it's a statement, not an expression:

switch (day) {
  case "MON", "TUE", "WED", "THU", "FRI" -> System.out.println("weekday");
  case "SAT", "SUN" -> System.out.println("weekend");
  default -> System.out.println("unknown");
}

The benefit over the old form: no break, no fall-through bugs, plus the multi-label cases above.

Exhaustiveness

When a switch expression assigns to a variable, the compiler requires that every possible input produces a value. For an enum, that means either covering all constants or providing a default:

enum Status { PENDING, ACTIVE, DONE }

Status s = Status.ACTIVE;

String label = switch (s) {
  case PENDING -> "waiting";
  case ACTIVE  -> "running";
  case DONE    -> "complete";
};   // no default needed — all enum values are covered

If you later add a new constant to the enum and forget to update the switch, the compiler will tell you. That's a strong correctness guarantee you don't get with if/else.

Pattern matching (Java 21+)

Java 21 made pattern matching for switch a standard feature. You can switch on the type of a value, and bind it to a typed variable inside the case:

Object o = 42;

String description = switch (o) {
  case Integer i when i < 0 -> "negative int: " + i;
  case Integer i             -> "non-negative int: " + i;
  case String s              -> "string of length " + s.length();
  case null                  -> "null value";
  default                    -> "something else";
};

The when clause is a guard — it narrows a case further with a boolean condition. This replaces a lot of instanceof chains.

A worked example

java— editable, runs on the server

What's next

We've covered conditionals. Next come the loops: the while loop is the simplest of them.

Practice

Practice

Inside an arrow-form switch expression with a block body, which keyword returns the value of that case?