Java yield Keyword in Switch Expressions (with Examples)

Learn the Java yield keyword with switch expression examples, arrow and colon cases, yield vs return vs break, exhaustiveness and contextual keyword rules.

yield returning the value of a switch expression case block

The yield keyword returns a value from a block of code inside a switch expression, the same way return returns a value from a method. We need it whenever a case must run more than one statement before it produces the value of the whole switch.

Most switch expressions use the short arrow form, where the value after -> is the result and no yield is needed. Once a case needs a log line, a calculation or a check, we open a block with braces, and yield hands the result back.

The following example maps a day of the week to a number of work hours, and the Friday case needs two statements.

DayOfWeek day = DayOfWeek.FRIDAY;
int hours = switch (day) {
    case SATURDAY, SUNDAY -> 0;
    case FRIDAY -> {
        int base = 8;
        yield base - 2;                 // short Friday
    }
    default -> 8;
};
int result = hours;                     // 6

Notice that yield sits inside the braces of the FRIDAY case only. We look at yield in arrow blocks and in old-style colon cases, compare it with return and break, cover exhaustiveness, and explain why yield is a contextual keyword that still works as a variable name.

1. Using yield in Arrow Case Blocks

In an arrow case, the code after -> is an expression, a block or a throw statement. A single expression is the value of the case, but a block must end every path with yield or throw, otherwise the code does not compile.

yield returning the value of a switch expression case block
Only the case block in braces needs yield to hand its value to the switch
static String shippingLabel(int weightKg) {
    return switch (weightKg / 10) {
        case 0 -> "small";
        case 1, 2 -> {
            String size = "medium";
            yield weightKg > 25 ? size + ", heavy" : size;
        }
        default -> {
            if (weightKg > 100) {
                throw new IllegalArgumentException("Too heavy: " + weightKg);
            }
            yield "large";
        }
    };
}
String parcel = shippingLabel(4);       // "small"
String box = shippingLabel(27);         // "medium, heavy"
String crate = shippingLabel(60);       // "large"
String piano = shippingLabel(300);      // IllegalArgumentException

The default case shows both ways to leave a block. An if without a yield on every path is a compile error, and the compiler reports it as a missing yield instead of failing at runtime.

// does not compile: the block can complete without yield
int bonus = switch (level) {
    case 1 -> {
        if (sales > 100) {
            yield 500;
        }
    }
    default -> 0;
};

2. Using yield in Colon Case Groups

A switch expression can also use the older case X: labels. In that form, the last group must end with yield or throw, because break is not allowed to leave a switch expression. An earlier group without either falls through to the next group, like in a switch statement.

static int daysIn(Month month, boolean leapYear) {
    return switch (month) {
        case FEBRUARY:
            yield leapYear ? 29 : 28;
        case APRIL, JUNE, SEPTEMBER, NOVEMBER:
            yield 30;
        default:
            yield 31;
    };
}
int feb = daysIn(Month.FEBRUARY, true);  // 29
int june = daysIn(Month.JUNE, false);    // 30
int may = daysIn(Month.MAY, false);      // 31

The arrow form is the better default, because it never falls through and needs yield only in blocks. The colon form is useful when we convert an old switch statement into an expression and want to keep its layout, and the Oracle switch guide shows both side by side.

3. yield vs return vs break

The yield keyword ends a switch expression with a value, return ends a method, and break ends a loop or a switch statement. The three are not interchangeable inside a switch expression.

KeywordLeavesCarries a valueAllowed inside a switch expression
yieldThe enclosing switch expressionYes, the result of the switchYes
returnThe enclosing method or lambdaYes, the method resultNo, compile error
breakThe enclosing loop or switch statementNoNo, compile error
continueThe current loop iterationNoNo, compile error

The restriction exists because an expression must always produce a value. If a return could jump out of the middle of a switch expression, the variable on the left side of the assignment would be left without a value. A loop inside a case block can still use break and continue for itself.

List<Integer> readings = List.of(3, 7, -1, 12);
String status = switch (readings.size()) {
    case 0 -> "empty";
    default -> {
        int firstNegative = -1;
        for (int i = 0; i < readings.size(); i++) {
            if (readings.get(i) < 0) {
                firstNegative = i;
                break;                  // leaves the for loop only
            }
        }
        yield firstNegative < 0 ? "ok" : "bad reading at " + firstNegative;
    }
};
String report = status;                 // "bad reading at 2"

4. Exhaustive switch Expressions

A switch expression must cover every possible input, because it always has to produce a value. For an enum or a sealed type, listing every constant or subtype is enough, and no default is needed. For int or String, we add a default case.

sealed interface Shape permits Circle, Square {}
record Circle(double radius) implements Shape {}
record Square(double side) implements Shape {}
static double area(Shape shape) {
    return switch (shape) {
        case Circle c -> {
            double r = c.radius();
            yield Math.PI * r * r;
        }
        case Square s -> s.side() * s.side();
    };
}
double square = area(new Square(3));     // 9.0
double circle = area(new Circle(1));     // 3.141592653589793

When we later add a Triangle to the permits list, every switch expression over Shape stops compiling until it handles the new type. That compile error is the main safety benefit of switch expressions over chains of if statements.

5. Is yield a Keyword or an Identifier?

The yield word is a contextual keyword. It acts as a keyword only where a yield statement can appear, so old code that uses yield as a variable or method name keeps compiling.

int yield = 5;                          // still a legal variable name
int doubled = yield * 2;                // 10

Two cases need attention. A class cannot be named yield, and a method named yield() must be called with a qualifier, such as this.yield() or Thread.yield(), because an unqualified yield(…) call would read as a yield statement.

The Thread.yield() method is unrelated to the keyword. It hints to the scheduler that the current thread can give up the CPU, and it has existed since Java 1.0. The keyword only returns values from switch expressions.

6. Java Version History of yield

Switch expressions took three releases to settle, and yield replaced an earlier design that used break with a value.

Java versionChangeJEP
Java 12Switch expressions in preview, with break value; to return a valueJEP 325
Java 13Second preview, break value; replaced by yield value;JEP 354
Java 14Switch expressions and yield become a standard featureJEP 361
Java 21Pattern matching for switch, with type patterns and when guardsJEP 441

Since Java 14, yield needs no compiler flags. Code from tutorials that still runs javac –enable-preview for switch expressions was written for Java 12 or 13.

7. yield Keyword FAQs

Developers who start with switch expressions ask these questions about yield.

7.1. Do we need yield with arrow cases?

Only when the case body is a block in braces. A single expression after ->, such as case 1 -> “one”;, is the value of the case without yield.

7.2. Can we use yield in a switch statement?

No. A switch statement produces no value, so yield is a compile error there. Inside a switch statement, we use break to leave it or return to leave the method.

7.3. Can we use yield outside of a switch?

No. The yield statement must be inside a switch expression, and it always returns from the innermost one. To return from a method, we use return.

7.4. What happens with nested switch expressions?

Each yield returns from the innermost switch expression that contains it. The outer switch needs its own yield to pass the value further out.

8. Conclusion

The yield keyword returns a value from a block inside a switch expression. Arrow cases need it only in braces, colon cases need it at the end of each group that does not fall through, and return, break and continue cannot leave a switch expression.

Because yield is a contextual keyword, it remains a legal variable name, and it has nothing to do with Thread.yield(). It became standard in Java 14, and with sealed types and pattern matching it makes exhaustive, value-returning switches the normal style in modern Java.

9. References

Happy Learning !!

Source Code on Github

Leave a Comment

Comments are closed.

About Us

HowToDoInJava provides tutorials and how-to guides on Java and related technologies.

It also shares the best practices, algorithms & solutions and frequently asked interview questions.