Back to Blog
Java

Java Switch Yield: Using yield in Switch Expressions

Learn how the yield keyword works in Java switch expressions, with syntax examples, common mistakes, and practical guidance.

JavaSwitch ExpressionsYield KeywordJava 14Syntax
Diagram showing a Java switch expression with yield keyword returning a value from multiple branches

Java's switch expressions, finalized in Java 14, let a switch produce a value. In block branches, the yield keyword returns that value from the expression. This article explains how yield works, how it differs from break, and where it fits in modern Java code.

What Switch Expressions Are

Before switch expressions became standard, switch was a statement that executed code blocks but did not produce a result. To assign a value based on a switch, you had to use a temporary variable and break statements:

String dayType; switch (day) { case MONDAY: case TUESDAY: case WEDNESDAY: case THURSDAY: case FRIDAY: dayType = "weekday"; break; case SATURDAY: case SUNDAY: dayType = "weekend"; break; default: throw new IllegalArgumentException("Invalid day: " + day); }

This is verbose and error-prone. A switch expression changes the model: the entire switch evaluates to a single value. The same logic becomes:

String dayType = switch (day) { case MONDAY, TUESDAY, WEDNESDAY, THURSDAY, FRIDAY -> "weekday"; case SATURDAY, SUNDAY -> "weekend"; default -> throw new IllegalArgumentException("Invalid day: " + day); };

Here, the arrow syntax implicitly returns the expression on the right side of the arrow. When a branch needs multiple statements or a more complex computation, you must use yield explicitly.

The yield Keyword Syntax

yield is a contextual keyword. It is treated specially inside a switch expression; outside that context, yield can still be used as an identifier, though doing so is confusing and not recommended.

The syntax is straightforward: inside a switch expression block, yield is followed by an expression that becomes the result of that branch. The block must be enclosed in braces, and yield must be the last statement in the block.

int numLetters = switch (day) { case MONDAY, FRIDAY, SUNDAY -> { System.out.println("Checking day: " + day); yield 6; } case TUESDAY -> { yield 7; } case THURSDAY, SATURDAY -> { yield 8; } case WEDNESDAY -> { yield 9; } default -> throw new IllegalStateException("Invalid day: " + day); };

Each yield statement produces the value of the switch expression for that branch. The type of a switch expression is inferred from the values produced by its branches; throw statements complete abruptly and do not contribute a value type. In this example, all branches yield int values, so numLetters is int.

yield vs break in Switch Statements

The older switch statement uses break to exit a case block. In a switch expression, you cannot use break to exit a branch; yield serves that role when a block needs to produce a value. yield not only exits the branch but also provides the value for the expression. Because the switch expression must resolve to a value, a bare break cannot be used to exit a branch, and the compiler rejects it.

If you write a break to exit a switch expression branch, the code will not compile. The compiler expects either an arrow expression or a block ending with yield (or a throw).

This distinction is important when migrating legacy code. Converting a switch statement to a switch expression requires replacing break with yield in block branches and removing the temporary variable assignment.

Using yield with Arrow Labels

Switch expressions support two label styles: traditional colon labels and arrow labels. Arrow labels (->) are more concise and do not require yield when the right-hand side is a single expression. However, if you need multiple statements in an arrow branch, you must use a block and yield.

String result = switch (code) { case 200 -> "OK"; case 404 -> { logNotFound(); yield "Not Found"; } default -> "Unknown"; };

With colon labels, every branch must complete with yield or throw. Arrow labels with a single expression are a shorthand; they are equivalent to a block that yields that expression.

Common Mistakes with yield

One frequent error is using yield as a statement outside a switch expression. Since yield is contextual, it only has special meaning inside a switch expression block. Outside that context, it can still be used as an identifier, but a statement such as yield 42; in a regular method or switch statement does not compile.

Another mistake is forgetting that a block branch must end with yield or throw. If you write a block without a final yield, the compiler rejects it because the branch does not produce a value. For example:

// This does not compile int x = switch (n) { case 1 -> { System.out.println("one"); // missing yield } default -> 0; };

The compiler will report that the block does not complete normally. Add yield at the end to fix it.

Also, yield cannot be used in an arrow branch that uses a single expression. The arrow form already produces the result, and yield is only valid inside a block.

When to Use Switch Expressions with yield

Switch expressions with yield are ideal when you need to compute a value based on several cases and want the logic to be a single expression. This improves readability by keeping the assignment and the branching together. Use them when:

  • The result is a value that will be assigned, returned, or passed to a method.
  • A branch may need several statements before producing a value.
  • You want to avoid mutable temporary variables.

For cases where you only need to execute side effects and no value is produced, a traditional switch statement remains appropriate. Switch expressions are not a replacement for all switches; they are a tool for value-producing logic.

Compatibility and Runtime Considerations

Switch expressions were previewed in Java 12 and Java 13. Java 13 introduced yield as part of the revised preview, replacing Java 12's break with a value. The feature was finalized in Java 14, so standard code using switch expressions and yield requires Java 14 or later at compile time. The compiler enforces type consistency and, when no default is present, exhaustiveness: for enums, every constant must be covered, and in newer Java versions with sealed types, all permitted subtypes must be covered as well.

At runtime, a switch expression selects and evaluates the chosen branch just as a switch statement does. The main benefit is compile-time safety: the exhaustiveness check helps ensure that value-producing switches handle all relevant inputs, and type inference lets the branches contribute to one result.

When upgrading an older codebase, be aware that yield is a contextual keyword: existing code that uses yield as an identifier will still compile as long as it is not inside a switch expression. However, for clarity, it is better to avoid using yield as an identifier in new code.

In summary, yield makes value-based branching logic in Java switch expressions more expressive and safer. By understanding its syntax and rules, you can write cleaner code that leverages modern Java language features.

How to Use yield in Java Switch Expressions | RYUSLOG DEV