4.3 The switch Expression
A switch expression evaluates to a value, as opposed to a switch statement that does not. Conceptually we can think of a switch expression as an augmented switch statement that returns a value. We look at both forms of the switch expression, defined using the colon notation and the arrow notation, how it yields a value, and compare it to the switch statement. The switch expression is analogous to the switch statement, except for the provision to return a value.
The yield Statement
The yield statement in a switch expression is analogous to the break statement in a switch statement. It can only be used in a switch expression, where the identifier yield is a contextual keyword only having a special meaning in the context of a switch expression.
yield
expression
;
Execution of the yield statement results in the expression being evaluated, and its value being returned as the value of the switch expression.
The switch Expression with the Colon (:) Notation
The switch expression with the colon notation has the same form as the switch statement with the colon notation (Figure 4.2), except that the execution of the switch body results in a value (or it throws an exception).
Example 4.6 is a reworking of Example 4.2 with seasons, where the group of statements associated with a case label print information about the season and return a constant of the enum type Season that is defined at (1). Note that the yield statement is the last statement in the group of statements associated with each case label. Execution of the yield statement results in its expression being evaluated, and its value being returned as the value of the switch expression, thereby also terminating the execution of the switch expression. Not surprisingly, a break or a return statement is not allowed in a switch expression. Note that the switch expression is on the right-hand side of the assignment statement defined at (2) and is terminated by a semicolon (;).
The fall-through of execution in the switch expression with the colon notation is analogous to that of the switch statement with the colon notation (Figure 4.3). If a group of statements associated with a case label does not end in a yield statement, execution continues with the next group of statements, if any.
The switch expression with the colon notation must be exhaustive, meaning the case labels, and if necessary the default label, must cover all values of the selector expression type. Non-exhaustive switch expressions will result in a compile-time error. The default label is typically used to make the switch expression exhaustive. In Example 4.6, the type of the selector expression is int, but the case labels only cover the int values from 1 to 12. A default label is necessary to cover the other int values or to throw an exception, as in this case, and make the switch expression exhaustive.
Example 4.6 A yield Statement in a switch Expression with the Colon Notation
public class SeasonsIII {
enum Season { WINTER, SPRING, SUMMER, FALL } // (1)
public static void main(String[] args) {
int monthNumber = 11;
Season season = switch(monthNumber) { // (2)
case 12: case 1: case 2: // (3)
System.out.println(“Snow in the winter.”);
yield Season.WINTER; // (4)
case 3, 4: case 5: // (5)
System.out.println(“Green grass in the spring.”);
yield Season.SPRING; // (6)
case 6, 7, 8: // (7)
System.out.println(“Sunshine in the summer.”);
yield Season.SUMMER; // (8)
case 9, 10, 11: // (9)
System.out.println(“Yellow leaves in the fall.”);
yield Season.FALL; // (10)
default: // (11)
throw new IllegalArgumentException(monthNumber + ” not a valid month.”);
}; // (12)
System.out.println(season);
}
}
Output from the program:
Yellow leaves in the fall.
FALL