The switch statement transfers control to one of several statements depending on
the value of an expression.
SwitchStatement:
switch (Expression)SwitchBlock SwitchBlock:
{SwitchBlockStatementGroupsoptSwitchLabelsopt}SwitchBlockStatementGroups:
SwitchBlockStatementGroup
SwitchBlockStatementGroupsSwitchBlockStatementGroup SwitchBlockStatementGroup:
SwitchLabelsBlockStatements SwitchLabels:
SwitchLabel
SwitchLabelsSwitchLabel SwitchLabel:
caseConstantExpression:
default :
The type of the Expression must be char, byte, short, or int, or a compile-time error occurs.
The body of a switch statement must be a block. Any statement immediately contained by the block may be labeled with one or more case or default labels. These labels are said to be associated with the switch statement, as are the values of the constant expressions (§15.27) in the case labels.
All of the following must be true, or a compile-time error will result:
case constant expression associated with a switch statement must be assignable (§5.2) to the type of the switch Expression.
case constant expressions associated with a switch statement may have the same value.
default label may be associated with the same switch statement.
In C and C++ the body of a switch statement can be a statement and statements with case labels do not have to be immediately contained by that statement. Consider the simple loop:
for (i = 0; i < n; ++i) foo();
where n is known to be positive. A trick known as Duff's device can be used in C
or C++ to unroll the loop, but this is not valid Java code:
int q = (n+7)/8;
switch (n%8) {
case 0: do { foo(); // Great C hack, Tom,
case 7: foo(); // but it's not valid in Java.
case 6: foo();
case 5: foo();
case 4: foo();
case 3: foo();
case 2: foo();
case 1: foo();
} while (--q >= 0);
}
Fortunately, this trick does not seem to be widely known or used. Moreover, it is less needed nowadays; this sort of code transformation is properly in the province of state-of-the-art optimizing compilers.
When the switch statement is executed, first the Expression is evaluated. If evaluation of the Expression completes abruptly for some reason, the switch statement completes abruptly for the same reason. Otherwise, execution continues by comparing the value of the Expression with each case constant. Then there is a choice:
case constants is equal to the value of the expression, then we say that the case matches, and all statements after the matching case label in the switch block, if any, are executed in sequence. If all these statements complete normally, or if there are no statements after the matching case label, then the entire switch statement completes normally.
case matches but there is a default label, then all statements after the matching default label in the switch block, if any, are executed in sequence. If all these statements complete normally, or if there are no statements after the default label, then the entire switch statement completes normally.
case matches and there is no default label, then no further action is taken and the switch statement completes normally.
If any statement immediately contained by the Block body of the switch statement completes abruptly, it is handled as follows:
break with no label, no further action is taken and the switch statement completes normally.
switch statement completes abruptly for the same reason. The case of abrupt completion because of a break with a label is handled by the general rule for labeled statements (§14.6).
As in C and C++, execution of statements in a switch block "falls through labels" in Java. For example, the program:
class Toomany {
static void howMany(int k) {
switch (k) {
case 1: System.out.print("one ");
case 2: System.out.print("too ");
case 3: System.out.println("many");
}
}
public static void main(String[] args) {
howMany(3);
howMany(2);
howMany(1);
}
}
contains a switch block in which the code for each case falls through into the code for the next case. As a result, the program prints:
many too many one too many
If code is not to fall through case to case in this manner, then break statements
should be used, as in this example:
class Twomany {
static void howMany(int k) {
switch (k) {
case 1: System.out.println("one");
break; // exit the switch
case 2: System.out.println("two");
break; // exit the switch
case 3: System.out.println("many");
break; // not needed, but good style
}
}
public static void main(String[] args) {
howMany(1);
howMany(2);
howMany(3);
}
}
one two many