Concepts / Fall Through and Case Grouping

Fall Through and Case Grouping

The traditional switch uses a colon after each case label, and a case label may hold one constant before Java 17.

  • Programming

Testing a Common Belief About Switch

Many people who learn Java switch statements come away believing that every case must end with a break statement, as if the language demanded it the way it demands a semicolon. The belief is understandable. Most switch statements in older code do end each case with break. But the rule is not part of the syntax itself. This article tests that belief, works out what the syntax really requires, and then examines the behaviors that make the traditional form tricky.

Before reading further, look at the small program below. The only unusual feature is that the first case has no break statement. Work out what it prints when n holds the value 1.

java

What do you think happens?

What do you think this program prints when n holds 1?

Reveal answer
Answer:

It prints two lines: one, then two.

The value 1 matches the first case, so execution starts at that label and prints one. Because there is no break after that statement, control does not leave the switch. It continues into the statements of the case 2 label, prints two, and then reaches the break, which exits the switch. The three label is never reached, and the default group does not run.

Reading the Anatomy of a Traditional Switch

A traditional switch statement begins with the keyword switch followed by an expression in parentheses. The expression is evaluated once. Its body is enclosed in braces and contains a series of case labels. Each case label is written as the keyword case, then a constant, then a colon. Under each label sits a group of statements, and that group can contain as many statements as you need.

The colon at the end of each label is the mark of the traditional form. The newer style replaces that colon with an arrow, which is why the two forms look different on the page even though both choose one group of statements to run. The diagram below labels the parts you must be able to find in any traditional switch.

switch (n)selector expression,evaluated oncecase 1:keyword, constant, thencolonprintln("one")statements under the labelbreak;optional, exits the switchdefault:optional fallback group
Which parts of a traditional switch must a learner locate and read? The selector expression, each case label with its colon, the statements under the label, the break, and the default group.

How the Jump Lands and Where Execution Continues

When the switch runs, the computer evaluates the expression once and compares the result with the constants in the case labels. It then jumps to the label whose constant matches. If no label matches, it jumps to the default case, provided one exists. From that starting point the computer executes statements in order. The jump itself does not stop execution. The computer begins reading statements at the chosen label and keeps going until something tells it to leave the switch.

The break statement is the thing that tells it to leave. A break placed at the end of a case causes the computer to jump past the closing brace of the switch, skipping every remaining case. The syntax does not force you to write one. A program with no break at all will still compile. Whether a break is present or absent is therefore a decision about the behavior you want, and that decision is where most switch bugs begin.

Stacking Labels to Group Several Values

A case label can sit directly above another case label with no statements between them. When that happens, both constants lead to the same place in the switch. This lets you treat several values as one group without repeating statements, as long as the group is intended. Writing several labels in a row is a deliberate form of fall through, because each empty label simply passes control down to the group that follows.

n = 2case 1:empty label, passes controldowncase 2:matched herecase 3:empty label, passes controldownprintln("small")shared body for 1, 2, and 3break;after closing bracematchesno statements betweenreaches shared bodythenjumps out
When several case labels sit above one body with no break between them, which values reach that body? Every stacked label leads to the same statements, and the break after them ends the group.
java
Output
small
Notes on the code
  • Labels 1, 2, and 3 are stacked, so all three lead to the same body.
  • The break after the shared body keeps control from falling into the medium group.
  • The default group runs only if no label matches.
Worked example

Tracing a Stacked Group

Trace the grouped switch above for n equal to 2, then for n equal to 5.

  1. 1
    Evaluate the selector

    n is 2. The expression is evaluated once and compared with the constants in the labels.

  2. 2
    Find the matching label

    The label case 2 matches. Execution jumps to that label, which is part of the stack that ends at case 3.

  3. 3
    Run the shared body

    Labels case 2 and case 3 have no statements between them, so control reaches the println small statement and prints small.

  4. 4
    Exit at the break

    The break after the shared body jumps past the closing brace, so the medium group and the default group are skipped.

  5. 5
    Trace n equal to 5

    For n equal to 5, the matching label is in the second stack. It prints medium and the break exits. The small body does not run.

Result

For n equal to 2 the output is small. For n equal to 5 the output is medium.

Best practice

When you intend a group, stack the labels with no statements between them and put one break after the shared body. This makes the grouping visible to a reader, so an empty label is not mistaken for a forgotten break.

Where the Default Case Fits

The default case is the fallback group of a switch. It is introduced by the keyword default followed by a colon, and it runs when none of the other case labels match the expression. The default case is optional. A switch with no default is perfectly valid. In that situation, if no label matches, the switch does nothing and execution continues after the closing brace.

The source does not require any particular position for the default group, but the most common convention places it last. Its statements follow the same fall through rules as any other case. If the default group has no break and it is the last group, the switch simply ends there. If you place the default in the middle, a missing break will cause it to fall into whatever comes next.

java
Output
unknown
seven
Notes on the code
  • The value 4 matches no label, so execution jumps to the default group.
  • The default group has no break, so it falls into the case 7 statements.
  • The break after the seven statement exits the switch.

Mistakes Beginners Make With Fall Through

  • Common mistake

    Assuming every case must end with break because most older code does

    Why it fails

    The break is not required by the syntax. The program compiles without it, and the behavior is a design decision.

    Do this instead

    Decide for each case whether control should leave the switch or continue into the next group, and write break only when you want the exit.

  • Common mistake

    Forgetting the break after the last statement of a case

    What it looks like

    case 1: println("one"); case 2: println("two"); break; — with n equal to 1 this prints one and two.

    Why it fails

    The program still runs and produces output, so the extra output can go unnoticed.

    Do this instead

    End each case that should stop with a break and trace one value through the switch to confirm.

  • Common mistake

    Treating a stacked empty label as a mistake

    Why it fails

    An empty label above another label is deliberate grouping, because control passes down to the shared statements.

    Do this instead

    Keep the stacked labels together and place the single break after the shared body so the grouping is clear.

  • Common mistake

    Putting default in the middle without a break

    What it looks like

    default: println("unknown"); case 7: println("seven"); break; — with n equal to 4 both lines print.

    Why it fails

    A default group without a break falls into the next case, which the reader may not expect.

    Do this instead

    Place default last by convention, or end the default group with a break if it is not last.

  • Common mistake

    Expecting the default case to run when a label matches, since default is a fallback only

Practice Tracing Control Through a Switch

MEDIUM

Consider this switch. Trace it for n equal to 1, n equal to 2, and n equal to 9, and write the output for each value.

int n = 1;
switch (n) {
    case 1:
        System.out.println("A");
    case 2:
        System.out.println("B");
        break;
    case 3:
        System.out.println("C");
        break;
    default:
        System.out.println("D");
}
Hints
  • Find the label that matches the value first, then follow statements downward.
  • A label with no break keeps control moving into the next group.
  • For 9, no case matches, so consider where the default group sits and whether it has a break.

Key Takeaways

  • The break statement is not required by the syntax. It is the instruction that makes execution jump past the end of the switch.
  • Omitting break causes fall through, where the statements of the following case also run. Fall through is legal and occasionally useful, but accidental fall through is a common source of bugs.
  • Stacking case labels with no statements between them groups several values under one shared body, which is a deliberate form of fall through.
  • The default case is optional, runs only when no other label matches, and follows the same fall through rules wherever it is placed.
  • Before Java 17, a traditional case label held one constant, and Java 17 allows a comma-separated list of constants in one label.