switch Statements and Expressions
When one value decides between many fixed choices, an else if chain (Lesson 5.5) ends up comparing the same variable over and over. A switch says it directly: look at one value, then jump to the case that matches it.
The Classic switch Statement
int autoMode = 2;
switch (autoMode)
{
case 1:
System.out.println("Drive forward");
break;
case 2:
System.out.println("Score one piece");
break;
case 3:
System.out.println("Score two pieces");
break;
default:
System.out.println("Do nothing");
break;
}
Java evaluates the value in parentheses once, jumps to the case whose label matches it, and runs the statements from there. break ends the whole switch — the same break that leaves a loop early in Lesson 5.8. default runs when no label matches, like the trailing else of an else if chain; it's optional in a switch statement, but leaving it off makes "do nothing" a real outcome.
Case labels must be fixed values, like 2 or "RED" — never a condition such as autoMode > 2. For ranges, use an if/else chain. You can switch on an int, a char, a String or an enum (Ch.11) — but not on a long, a double or a boolean.
Fall-Through: What Happens Without break
Leave out a break, and execution doesn't stop at the next label — it falls through and keeps running the following case's statements, ignoring that case's label, until it reaches a break or the end of the switch:
switch (autoMode)
{
case 1:
System.out.println("Drive forward");
// no break: falls through into case 2
case 2:
System.out.println("Score one piece");
break;
default:
System.out.println("Do nothing");
break;
}
With autoMode set to 1, this prints both Drive forward and Score one piece. Fall-through is occasionally what you want, but far more often it's a forgotten break.
Several Labels, One Action
When several values should do the same thing, list them in one case, separated by commas:
switch (buttonNumber)
{
case 1, 2:
System.out.println("Intake");
break;
case 3:
System.out.println("Shoot");
break;
default:
System.out.println("Unmapped button");
break;
}
Older code gets the same effect with fall-through, stacking case 1: and case 2: on separate lines with nothing between them. The comma form says it more clearly.
Switching on a String
String alliance = "RED";
switch (alliance)
{
case "RED":
System.out.println("Start on the left");
break;
case "BLUE":
System.out.println("Start on the right");
break;
default:
System.out.println("Unknown alliance");
break;
}
A String case matches only the exact same text, capital letters included — "red" would land in default. (Ch.6 explains how Java compares Strings.)
The Arrow Form: No Fall-Through
Writing case ... -> instead of case ...: gives each case its own separate body. It never falls through, so there's no break to forget:
switch (autoMode)
{
case 1 -> System.out.println("Drive forward");
case 2 ->
{
System.out.println("Score one piece");
System.out.println("Then back up");
}
case 3, 4 -> System.out.println("Score two pieces");
default -> System.out.println("Do nothing");
}
A case with one statement puts it right after the arrow; a case with several wraps them in braces. One switch must use one form throughout — you can't mix : and -> cases. For new code, the arrow form is usually the better choice.
switch Expressions: Producing a Value
A switch can also produce a value, the way ?: does in Lesson 5.5, but for any number of choices:
int autoMode = 3;
String plan = switch (autoMode)
{
case 1 -> "Drive forward";
case 2 -> "Score one piece";
case 3, 4 -> "Score two pieces";
default -> "Do nothing";
};
System.out.println(plan); // Score two pieces
Each case's value becomes the value of the whole switch. Two rules come with that. The semicolon after the closing brace is required, because the switch is part of an assignment statement. And a switch expression must be exhaustive: every possible value has to produce a result, so a switch expression on an int or a String needs a default.
yield: When a Case Needs More Than One Line
If a case in a switch expression needs to do some work before producing its value, give it a block and hand the value back with yield:
double speed = switch (gear)
{
case 1 -> 0.3;
case 2 -> 0.6;
case 3 ->
{
System.out.println("Top gear: watch the corners");
yield 1.0;
}
default -> 0.0;
};
yield means "this is the switch's value" — return would try to leave the whole method instead. yield also replaces break if you ever write a switch expression in the colon form (case 1: yield 0.3;).
switch and Enums (Ch.11)
switch is at its best with enums, the named sets of choices that Ch.11 introduces — that chapter picks up right where this lesson leaves off. One Java version note to carry there: on Java 21 and later, including Java 25 (this course's target), an enum case label can be written either bare (case INTAKE ->) or qualified with the enum's name (case ArmPosition.INTAKE ->). On Java 17, only the bare name compiles. Everything else in this lesson — arrow cases, comma-separated labels, switch expressions and yield — has been standard since Java 14, so it works the same on Java 17 and Java 25.
Common Pitfalls
- Forgetting
breakin the colon form. Execution falls through and runs the next case's statements too. The arrow form can't fall through, which is a good reason to prefer it. - Writing a condition as a case label.
case autoMode > 2:won't compile — labels are fixed values. Use anif/elsechain for ranges. - Leaving out
defaultin aswitchexpression on anintorString. It won't compile, because some values would have no result. - Forgetting the semicolon after a
switchexpression.String plan = switch (autoMode) { ... }needs a;after the closing brace, like any other assignment. - Switching on a
Stringthat might benull. Theswitchthrows aNullPointerExceptionbefore checking any case, evendefault.
Key Takeaways
- A
switchmatches one value against fixed case labels; it works onint,char,Stringand enum values. - In the colon form, each case needs a
break; without one, execution falls through into the next case.defaultcatches every value no label matched. - The arrow form (
case 1 ->) never falls through, andcase 1, 2lists several labels for one action. - A
switchexpression produces a value and must cover every possible input, sointandStringswitch expressions need adefault. yieldhands back the value from a multi-line block inside aswitchexpression.- On Java 21+ an enum case label may be qualified (
case ArmPosition.INTAKE); Java 17 accepts only the bare constant name.
Derived from: nothing upstream — written for this course (content-audit decision D4); AP CSA doesn't cover switch.