Sunday, November 9, 2008

Switch Statements

Switch

The switch statement is Java's multiway branch statement. It provides an easy way to dispatch execution to different parts of your code based on the value of an expression. As such, it often provides a better alternative than a large series of if-else-if statements.

 

Here is the general form of a switch statement:

switch (expression) {

case value1:

// statement sequence

break;

case value2:

// statement sequence

break;

...

case valueN:

// statement sequence

break;

default:

// default statement sequence

}

 

The expression must be of type byte, short, int, or char; each of the values specified in the case statements must be of a type compatible with the expression. Each case value must be a unique literal (that is, it must be a constant, not a variable). Duplicate case values are not allowed.

 

The switch statement works like this: The value of the expression is compared with each of the literal values in the case statements. If a match is found, the code sequence following that case statement is executed. If none of the constants matches the value of the expression, then the default statement is executed. However, the default statement is optional. If no case matches and no default is present, then no further action is taken.

 

The break statement is used inside the switch to terminate a statement sequence.

When a break statement is encountered, execution branches to the first line of code that follows the entire switch statement. This has the effect of "jumping out" of the switch.

 

Here is a simple example that uses a switch statement:

LANGUAGE

// A simple example of the switch.

class SampleSwitch {

public static void main(String args[]) {

for(int i=0; i<6; i++)

switch(i) {

case 0:

System.out.println("i is zero.");

break;

case 1:

System.out.println("i is one.");

break;

case 2:

System.out.println("i is two.");

break;

case 3:

System.out.println("i is three.");

break;

default:

System.out.println("i is greater than 3.");

}

}

}

 

The output produced by this program is shown here:

i is zero.

i is one.

i is two.

i is three.

i is greater than 3.

i is greater than 3.

 

As you can see, each time through the loop, the statements associated with the case constant that matches i are executed. All others are bypassed. After i is greater than 3, no case statements match, so the default statement is executed.

 

The break statement is optional. If you omit the break, execution will continue on into the next case. It is sometimes desirable to have multiple cases without break statements between them.

 

For example, consider the following program:

 

// In a switch, break statements are optional.

class MissingBreak {

106  

public static void main(String args[]) {

for(int i=0; i<12; i++)

switch(i) {

case 0:

case 1:

case 2:

case 3:

case 4:

System.out.println("i is less than 5");

break;

case 5:

case 6:

case 7:

case 8:

case 9:

System.out.println("i is less than 10");

break;

default:

System.out.println("i is 10 or more");

}

}

}

 

This program generates the following output:

i is less than 5

i is less than 5

i is less than 5

i is less than 5

i is less than 5

i is less than 10

i is less than 10

i is less than 10

i is less than 10

i is less than 10

i is 10 or more

i is 10 or more

 

As you can see, execution falls through each case until a break statement (or the end of the switch) is reached. While the preceding example is, of course, contrived for the sake of illustration, omitting the break statement has many practical applications in real programs.

 

To sample its more realistic usage, consider the following rewrite of the season example shown earlier. This version uses a switch to provide a more efficient implementation.

 

// An improved version of the season program.

class Switch {

public static void main(String args[]) {

int month = 4;

String season;

switch (month) {

case 12:

case 1:

case 2:

season = "Winter";

break;

case 3:

case 4:

case 5:

season = "Spring";

break;

case 6:

case 7:

case 8:

season = "Summer";

break;

case 9:

case 10:

case 11:

season = "Autumn";

break;

default:

season = "Bogus Month";

}

System.out.println("April is in the " + season + ".");

}

}

LANGUAGE

Nested switch Statements

You can use a switch as part of the statement sequence of an outer switch. This is called a nested switch. Since a switch statement defines its own block, no conflicts arise between the case constants in the inner switch and those in the outer switch.

 

For example, the following fragment is perfectly valid:

 

switch(count) {

case 1:

switch(target) { // nested switch

case 0:

System.out.println("target is zero");

break;

case 1: // no conflicts with outer switch

System.out.println("target is one");

break;

}

break;

case 2: // ...

 

Here, the case 1: statement in the inner switch does not conflict with the case 1: statement in the outer switch. The count variable is only compared with the list of cases at the outer level. If count is 1, then target is compared with the inner list cases.

 

In summary, there are three important features of the switch statement to note:

 

Ø      The switch differs from the if in that switch can only test for equality, whereas if can evaluate any type of Boolean expression. That is, the switch looks only for a match between the value of the expression and one of its case constants.

Ø      No two case constants in the same switch can have identical values. Of course, a switch statement enclosed by an outer switch can have case constants in common.

Ø      A switch statement is usually more efficient than a set of nested ifs.

 

The last point is particularly interesting because it gives insight into how the Java compiler works. When it compiles a switch statement, the Java compiler will inspect each of the case constants and create a "jump table" that it will use for selecting the path of execution depending on the value of the expression.

 

Therefore, if you need to select among a large group of values, a switch statement will run much faster than the equivalent logic coded using a sequence of if-elses. The compiler can do this because it knows that the case constants are all the same type and simply must be compared for equality with the switch expression. The compiler has no such knowledge of a long list of if expressions.

No comments: