3.4 The switch Statement & Multi-Way Branching

Key Takeaways

  • In Java SE 8, switch selector expressions permit only byte, short, char, int, their respective wrapper classes (Byte, Short, Character, Integer), String (since Java 7), and enum types.
  • The data types long, float, double, and boolean (and their corresponding wrapper classes) are strictly prohibited as switch selectors and cause compile-time errors.
  • Every case label must be a compile-time constant expression whose value is assignable to the selector type without narrowing, and duplicate case values are strictly forbidden.
  • Omitting a break statement triggers fall-through execution, causing subsequent case bodies and default to execute sequentially without re-evaluating case conditions until a break or closing brace is reached.
  • The default label is optional and may appear at any position (top, middle, or bottom) inside the switch block; it executes only if no case matches, but will fall through into subsequent cases if not terminated by break.
Last updated: September 2026

3.4 The switch Statement & Multi-Way Branching

[!NOTE] Exam Focus: The switch statement is a major focus area of Exam 1Z0-811. Key testing points include identifying valid and invalid selector types in Java SE 8, compile-time constant requirements for case labels, duplicate label compilation errors, fall-through execution when break statements are omitted, and default label placement and cascading execution.

The switch statement provides multi-branch selection based on the evaluated equality of a single selector expression against multiple constant case values. It serves as a structured, optimized alternative to lengthy if-else-if chains testing the same variable for discrete values.

General Syntax

switch (selectorExpression) {
    case constant1:
        // statements executed when selectorExpression == constant1
        break;
    case constant2:
        // statements executed when selectorExpression == constant2
        break;
    default:
        // statements executed when no case matches
        break;
}

1. Permissible vs. Forbidden Selector Types in Java SE 8

A cornerstone objective of the 1Z0-811 examination is verifying whether a variable type can serve as the selector expression in a switch statement.

+------------------------------------+-------------------------------------+
|    PERMISSIBLE SWITCH TYPES        |       FORBIDDEN SWITCH TYPES        |
+------------------------------------+-------------------------------------+
| byte       (and Byte wrapper)      | long       (and Long wrapper)       |
| short      (and Short wrapper)     | float      (and Float wrapper)      |
| char       (and Character wrapper) | double     (and Double wrapper)     |
| int        (and Integer wrapper)   | boolean    (and Boolean wrapper)    |
| String     (Java 7+)               | Any other object type (Scanner, etc)|
| enum types (Java 5+)               |                                     |
+------------------------------------+-------------------------------------+

Rationale for Forbidden Types

  1. long (and Long): 64-bit integer values are not permitted because switch jump tables in bytecode (tableswitch and lookupswitch) are designed specifically for 32-bit offsets.
  2. float and double: Floating-point rounding inaccuracies inherent to binary IEEE 754 representations make exact equality checks unreliable.
  3. boolean: A boolean choice has only two states (true or false) and is designed for an if-else statement; permitting switch(boolean) would add unnecessary language complexity.
long orderId = 1000L;
// COMPILE ERROR: incompatible types: possible lossy conversion from long to int
// switch (orderId) { ... }

double taxRate = 0.08;
// COMPILE ERROR: selector type not allowed
// switch (taxRate) { ... }

2. Case Label Requirements & Compile-Time Constants

The Java compiler enforces strict grammatical rules on values following the case keyword:

1. Compile-Time Constant Requirement

Every case label must be a compile-time constant expression. A constant expression can be fully evaluated to a fixed value during compilation:

  • Literal values (e.g., case 1:, case 'X':, case "ACTIVE":)
  • final variables initialized inline with a compile-time constant
  • Constant arithmetic expressions (e.g., case 2 + 3:)
  • Enum constants (e.g., case NORTH:)
final int MIN_SCORE = 60; // Compile-time constant
int normalVar = 75;       // Non-final variable
final int blankFinal;     // Blank final
blankFinal = 80;

int score = 85;
switch (score) {
    case MIN_SCORE:       // COMPILES: MIN_SCORE is a final compile-time constant
        break;
    // case normalVar:   // COMPILE ERROR: constant expression required
    //     break;
    // case blankFinal:  // COMPILE ERROR: blank final is NOT a compile-time constant
    //     break;
}

2. Range Constraints and Type Assignability

The constant expression in a case label must be assignable to the switch expression's data type without narrowing:

byte b = 10;
switch (b) {
    case 100: // Compiles: 100 fits in byte (-128 to 127)
        break;
    // case 130: // COMPILE ERROR: possible lossy conversion from int to byte (130 exceeds byte range)
    //     break;
}

3. Duplicate Case Labels Are Forbidden

No two case labels in the same switch block may evaluate to the identical value:

int code = 2;
switch (code) {
    case 1: break;
    case 2: break;
    // case 1 + 1: break; // COMPILE ERROR: duplicate case label (1 + 1 evaluates to 2)
}

3. The break Statement and Fall-Through Mechanics

The break statement halts the execution of the switch block and transfers control to the statement immediately following the switch's closing brace }.

The Fall-Through Mechanism

If a matching case block does not terminate with a break (or return), execution falls through into subsequent cases, executing their statement bodies without testing their case conditions, until a break is encountered or the switch block ends!

int day = 2;
switch (day) {
    case 1:
        System.out.print("Mon ");
    case 2:
        System.out.print("Tue "); // Matches: prints "Tue "
    case 3:
        System.out.print("Wed "); // Falls through: prints "Wed " (no condition check!)
        break;                    // Halts switch execution
    case 4:
        System.out.print("Thu ");
}
// Output: Tue Wed 

Deliberate (Intentional) Fall-Through

Developers frequently omit break statements deliberately to group multiple case labels that share common handling logic:

char grade = 'B';
switch (grade) {
    case 'A':
    case 'B':
    case 'C':
        System.out.println("Passing grade");
        break;
    case 'D':
    case 'F':
        System.out.println("Failing grade");
        break;
    default:
        System.out.println("Invalid grade");
        break;
}

4. The default Label: Placement and Execution Dynamics

The default label defines the block of code executed when no case constant matches the selector expression.

Key Rules for default

  1. Optional: A switch statement does not require a default label. If no case matches and no default exists, the switch executes as a no-op.
  2. Placement Anywhere: The default label can appear anywhere inside the switch block—at the top, in the middle, or at the bottom.
  3. Evaluation Timing: Regardless of its textual position inside the block, default is evaluated only after all case labels have failed to match.
  4. Fall-Through from Default: If default is placed anywhere other than the very bottom and omits a break, execution cascades directly into the case labels beneath it!
int code = 99; // Does not match 1 or 2
switch (code) {
    default:
        System.out.print("Def "); // Evaluates because no case matches
    case 1:
        System.out.print("One "); // Falls through into case 1!
        break;
    case 2:
        System.out.print("Two ");
}
// Output: Def One 

[!WARNING] Exam Trap: When default is at the top of a switch block, candidates often assume it executes first. It does not execute first—Java checks all case constants first. However, if no case matches, default executes, and if it lacks a break, execution cascades straight into subsequent cases!


5. Strings and Null Safety in Switch

Since Java 7, String objects can be used as switch selectors. The comparison is case-sensitive and evaluates using String.equals():

String role = "ADMIN";
switch (role) {
    case "admin": // Will NOT match ("ADMIN" is uppercase)
        System.out.println("User admin");
        break;
    case "ADMIN": // Matches
        System.out.println("System administrator");
        break;
}

The Null Selector Trap

If a String (or boxed wrapper object) reference holding null is passed into a switch statement, Java throws an unchecked java.lang.NullPointerException at runtime when attempting to evaluate the selector:

String status = null;
// Throws NullPointerException at runtime!
switch (status) {
    case "OK":
        System.out.println("OK");
        break;
    default:
        System.out.println("Unknown");
}

6. Architectural Comparison: switch vs. if-else-if

Architectural Featureswitch Statementif-else-if Ladder
Tested ConditionStrict equality against discrete constantsArbitrary boolean expressions (<, >, !=, &&, etc.)
Supported Typesbyte, short, char, int, Wrappers, String, enumsAny data type evaluated via boolean expressions
Range EvaluationCannot test ranges directly (case 1..10 is invalid)Excels at range checks (score >= 80 && score < 90)
Evaluated VariablesTests only a single expressionCan evaluate multiple independent variables simultaneously
Bytecode CompilationCompiled to tableswitch (O(1)) or lookupswitch (O(log n))Evaluated sequentially O(n)
Fall-Through ControlRequires explicit break to prevent fall-throughMutually exclusive branches by default
Loading diagram...
Switch Statement Execution Flow, Case Matching, and Fall-Through Cascading
Test Your Knowledge

Which of the following variable declarations CANNOT be used as the selector expression in a Java SE 8 switch statement?

A
B
C
D
Test Your Knowledge

What is the console output when the following Java code executes?

int code = 2;
switch (code) {
    default:
        System.out.print("Def ");
    case 1:
        System.out.print("One ");
        break;
    case 2:
        System.out.print("Two ");
    case 3:
        System.out.print("Three ");
        break;
    case 4:
        System.out.print("Four ");
}

A
B
C
D
Test Your Knowledge

Consider the following Java method snippet:

final int BASE = 10;
int offset = 5;
final int limit;
limit = 20;
int val = 15;

switch (val) {
    case BASE: 
        System.out.println("Base"); 
        break;
    // Which case label below causes a compilation error?
}
Which of the following case labels causes a compile-time error if added to the switch statement?

A
B
C
D