Case Labels Are Just Labels


A case label is just a label. The Java VM uses the case labels only when the Java VM initially encounters the switch statement. Once Java has located the matching case label and transferred control to it, it ignores the remainder of the case labels. Java executes the remainder of the code in the switch statement in top-to-bottom order. Java blissfully ignores the case labels and the default label, through to the end of the switch statement (or until another statement such as return TRansfers control.)[1]

[1] You'll learn more about statements to transfer control in Lesson 7.

The following example demonstrates how the switch statement flows:

 public void testSwitchResults() {    enum Score       { fieldGoal, touchdown, extraPoint,       twoPointConversion, safety };    int totalPoints = 0;    Score score = Score.touchdown;    switch (score) {       case fieldGoal:          totalPoints += 3;       case touchdown:          totalPoints += 6;       case extraPoint:          totalPoints += 1;       case twoPointConversion:          totalPoints += 2;       case safety:          totalPoints += 2;    }    assertEquals(6, totalPoints); } 

The test fails:

 junit.framework.AssertionFailedError: expected<6> but was<11> 

Since score was set to Score.touchdown, the Java VM transferred control to the line following the corresponding case label:

 case touchdown:    totalPoints += 6; 

Once Java executed that line, it then executed the next three statements (and ignored the case labels):

 case extraPoint:  // ignored    totalPoints += 1; case twoPointConversion:  // ignored    totalPoints += 2; case safety:    // ignored    totalPoints += 2; 

Total points thus is 6 plus 1 plus 2 plus 2, or 11. Test failure!

You obtain the desired behavior by inserting a break statement at the end of each section of code following a case label:

 public void testSwitchResults() {    enum Score       { fieldGoal, touchdown, extraPoint,       twoPointConversion, safety };    int totalPoints = 0;    Score score = Score.touchdown;    switch (score) {       case fieldGoal:          totalPoints += 3;          break;       case touchdown:          totalPoints += 6;          break;       case extraPoint:          totalPoints += 1;          break;       case twoPointConversion:          totalPoints += 2;          break;       case safety:          totalPoints += 2;          break;    }    assertEquals(6, totalPoints); } 

The break statement is another statement that transfers control flow. It transfers control out of the switch statement to the next statement following. In the example, executing any break statement results in control being transferred to the assertEquals statement.

Multiple case labels can precede a statement appearing within the switch statement:

 switch (score) {    case fieldGoal:       totalPoints += 3;       break;    case touchdown:       totalPoints += 6;       break;    case extraPoint:       totalPoints += 1;       break;    case twoPointConversion:    case safety:       totalPoints += 2;       break; } 

If score matches either Score.twoPointConversion or Score.safety, the code adds two points to the total.

In addition to switching on enum values, you can switch on char, byte, short, or int values. You cannot, unfortunately, switch on String values.

Your code should not contain a lot of switch statements. Also, it should not contain lots of multiple if statements that accomplish the same goal. Often, you can eliminate switch statements in favor of polymorphic solutions, as in the previous lesson. Your main guides as to whether you should replace switch statements with polymorphism are duplication and frequency/ease of maintenance.

Before continuing, refactor RegularGradingStrategy to use a switch statement instead of multiple if statements.



Agile Java. Crafting Code with Test-Driven Development
Agile Javaв„ў: Crafting Code with Test-Driven Development
ISBN: 0131482394
EAN: 2147483647
Year: 2003
Pages: 391
Authors: Jeff Langr

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net