14.9 The switch Statement

The switch statement transfers control to one of several statements depending on the value of an expression.

SwitchStatement:
switch ( Expression ) SwitchBlock
SwitchBlock:
{ SwitchBlockStatementGroupsopt SwitchLabelsopt }
SwitchBlockStatementGroups:
SwitchBlockStatementGroup
SwitchBlockStatementGroups SwitchBlockStatementGroup
SwitchBlockStatementGroup:
SwitchLabels BlockStatements
SwitchLabels:
SwitchLabel
SwitchLabels SwitchLabel
SwitchLabel:
case ConstantExpression :
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:

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:

If any statement immediately contained by the Block body of the switch statement completes abruptly, it is handled as follows:

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); }
}

This program prints:


one
two
many