skip to content

Switch Expressions

Arrow-form switch produces a value, has no fall-through, uses yield for block bodies, and must be exhaustive. Interviewers use it to see whether you have moved on from the statement form and understand why exhaustiveness matters.

part ofJavaoverview, primer and where to startread it →
on this pageshow

questions

5

What is a switch expression in Java, and how does the arrow (case ->) form differ from the traditional switch statement?

level: juniorimportance: must knowfreq 70%

answer

  1. Expression returns a value; statement does not
  2. Arrow = no fall-through, no break
  3. Comma groups labels: case A, B ->
  4. Standardized in Java 14
  5. Semicolon after the closing brace when assigning

basics

~10 s

A switch expression produces a value you can assign to a variable. The arrow form 'case X -> result;' runs only the matching branch with no fall-through, so you don't need break statements.

solid answer

~40 s

A switch expression (standardized in Java 14) evaluates a value and returns a result, unlike the old switch statement that only performs side effects. The arrow form 'case LABEL -> expression;' associates each label with a single expression or block; only the matched branch executes and there is no fall-through, so 'break' is unnecessary. Multiple labels can share one branch with commas: 'case A, B -> ...'. Because it is an expression, you can assign it: 'int n = switch (day) { case MON, TUE -> 1; default -> 0; };'. It can also still be used in statement position. Compared to the colon form, the arrow form is more concise, avoids accidental fall-through bugs, and enables exhaustiveness checking by the compiler.

go deeper

for a junior

Knows a switch expression returns a value and the arrow form removes break/fall-through; can write a simple 'int n = switch(x){...}'.

for a middle

Explains expression vs statement, comma-grouped labels, and that the body can be an expression or block; knows the Java 14 standardization.

for a senior

Contrasts arrow vs colon semantics precisely, mentions exhaustiveness benefits, and chooses switch expressions to eliminate fall-through bug classes in real code.

for a principal

Frames switch expressions within the broader pattern-matching roadmap (sealed types, record/pattern labels) and guides team conventions on when to adopt arrow form vs legacy switch.

## Background: the old switch statement Java has long had a `switch` **statement**. A statement performs an action but does not produce a value. The classic form uses colons and `break`: ```java switch (day) { case MONDAY: case TUESDAY: System.out.println("start"); break; // without break, execution "falls through" to the next case default: System.out.println("other"); } ``` Two pain points: (1) **fall-through** — if you forget `break`, control continues into the next `case`, a frequent source of bugs; (2) it is a statement, so to compute a value you must declare a variable and assign inside each branch. ## What a switch *expression* is An **expression** is a piece of code that evaluates to a value (like `2 + 2` or a method call). A **switch expression** (a preview in Java 12–13, **standardized in Java 14**) is a switch that *produces a value*. You can therefore assign its result directly. ## The arrow (`->`) form The arrow form writes `case LABEL -> body;`. The `body` is either a single expression, a `throw`, or a `{ ... }` block. Key properties: - **No fall-through.** Only the matched branch runs; you never need `break`. - **Multiple labels per branch** with commas: `case SATURDAY, SUNDAY -> ...`. - **Returns a value** when used as an expression. ```java int numLetters = switch (day) { case MONDAY, FRIDAY, SUNDAY -> 6; case TUESDAY -> 7; case THURSDAY, SATURDAY -> 8; case WEDNESDAY -> 9; }; ``` Here the whole `switch (...) { ... }` evaluates to an `int`, assigned to `numLetters`. Note the semicolon after the closing brace — it terminates the assignment statement. ## Arrow form vs. colon form Both forms can be used in *either* statement or expression position, and you can use colons with expressions too — but the **arrow form** is the modern default because it removes fall-through and reads as a clean label-to-result mapping. The colon form keeps fall-through semantics. ## When the body is a block If a branch needs multiple statements, use a block and `yield` to produce the value (covered in a separate question): ```java int n = switch (day) { case MONDAY -> { log(day); yield 1; } default -> 0; }; ``` ## Why it matters The switch expression with arrows is safer (no accidental fall-through), more concise, and — when switching over an enum or sealed type — lets the **compiler verify exhaustiveness** (all cases covered), turning a class of runtime bugs into compile errors.

  • Can a switch expression be used where a statement is expected?
    Yes. A switch expression can stand in statement position (its value simply discarded), and the arrow form can also be used as a pure statement. Conversely the old colon/break form can be adapted to expressions, but arrow form is preferred.
  • How do you group several labels into one branch?
    List them comma-separated before the arrow: 'case MONDAY, FRIDAY, SUNDAY -> 6;'. Each label still must be unique across the switch.

saying these in an interview costs you the question

  • Thinking you still need 'break' in the arrow form (you don't)
  • Believing arrow form allows fall-through between cases
  • Saying switch expressions arrived in Java 8 (they were standardized in Java 14)
  • Confusing the colon ':' form with the arrow '->' form

context

open as a page

When and how do you use 'yield' in a switch expression?

level: middleimportance: must knowfreq 60%

basics

~10 s

Use 'yield' to return a value from a switch branch that is a block ({ ... }) and needs more than one statement. Single-expression arrow branches don't need it; they return their value directly.

open as a page

What does exhaustiveness mean for a switch expression, and how does the compiler enforce it?

level: seniorimportance: must knowfreq 58%

basics

~10 s

A switch expression must cover every possible input value. You either add a 'default' branch or list all values (e.g. every enum constant). If you don't, it won't compile.

open as a page

How does a switch expression differ from a switch statement, and when would you choose each?

level: middleimportance: should knowfreq 50%

basics

~10 s

A switch statement does an action and returns nothing; a switch expression computes and returns a value. Use the expression to assign or return a result; use the statement for pure side effects.

open as a page

How do null selectors and adoption tradeoffs affect choosing arrow switch expressions in a codebase?

level: principalimportance: nice to knowfreq 30%

basics

~20 s

A traditional switch throws NullPointerException if the selector is null. Classic arrow switch expressions over enums/strings do the same unless you guard for null first. Adopting them widely improves safety but needs a recent Java version.

open as a page