Switch Statement & Switch Expressions
When you need to pick one path out of many based on a single value, a chain of if-else gets noisy fast. switch says it once, cleanly. This lesson covers the classic statement, the modern arrow-form expression, fall-through, and yield .
Learn Switch Statement & Switch Expressions in our free Java course — a beginner-friendly interactive lesson with worked examples, a practice exercise and a…
Part of the free Java course at LearnCodingFast — hands-on lessons with examples you run in your browser, plus practice exercises and a quick quiz.
Before You Start
You should be comfortable with if-else conditionals and Enums — switch pairs beautifully with enums. The modern arrow form requires Java 14 or newer (which is everything from 2020 onward).
What You'll Learn
The Big Idea — A Telephone Switchboard
💡 Analogy: A switch is an old telephone switchboard operator. You give one input — "extension 3" — and the operator connects you to exactly one line. A chain of if-else is like a security guard checking a list top to bottom, asking "is it 1? is it 2? is it 3?" over and over. The switchboard jumps straight to the right line.
There are two flavours. The classic statement (with case ... : and break ) has been in Java forever and runs side effects. The switch expression (with case ... -> ) is newer, returns a value, and removes the fall-through trap. We'll learn both, but you should reach for the arrow form in new code.
1️⃣ The Classic switch Statement
The original form evaluates a value once, then jumps to the matching case label. Each branch ends with break to stop execution from sliding into the next case. default is the catch-all when nothing matched.
Notice two cases can share a block by stacking labels ( case 6: case 7: ). Read the worked example, then run it.
2️⃣ Fall-Through — the Classic Trap
In the classic form, once a case matches, execution keeps running through every following case until it hits a break . Forget the break and you get extra, unintended output. This is the single most common switch bug. The example below omits every break on purpose so you can see it happen — execution enters at case 2 and tumbles all the way down.
3️⃣ The Modern switch Expression (Java 14+)
The arrow form fixes everything awkward about the classic switch:
- No break needed — only the matching branch runs, then it stops. No fall-through.
- It returns a value — you can assign the whole switch to a variable.
- One label can list multiple values — case 12, 1, 2 -> ... .
- It must be exhaustive — cover every case, or include a default , or it won't compile.
4️⃣ Multi-Line Branches with yield
A single-expression branch ( case PENNY -> 1; ) returns its value automatically. But when a branch needs several statements, wrap them in { } and end with yield to hand back the result. Switching over an enum is special: if you cover every constant, you don't even need a default — the compiler proves the switch is exhaustive.
5️⃣ Switching on Strings
You can switch on a String — handy for parsing commands or menu input. Two things to remember: matching is case-sensitive ( "stop" ≠ "STOP" ), and switching on a null String throws a NullPointerException , so guard against null first.
🧩 Reorder Challenge
These lines build a switch expression that turns a traffic-light colour into an action, then prints it. They've been shuffled. Put them in the right order in your head, then check.
Declare the input first, open the switch, list the cases, close it with }; (note the semicolon — it's an expression), then print.
🧠 Quick Recall
Predict the output before opening each answer.
Answer: two then three . Matching enters at case 2 , prints "two", and — with no break — falls through into case 3 , prints "three", then hits break and stops. case 4 never runs.
Answer: 3 . The arrow form runs only the matching branch and returns its value, which is assigned straight to size . No break, no fall-through.
Answer: computing then five . The block branch runs the println side effect, then yield "five" hands the value back, which is printed on the next line.
🎯 Your Turn #1 — Modernise a switch
Convert the classic colon-form switch into a switch expression using the arrow form. Run it and confirm the output.
🎯 Your Turn #2 — Categorise HTTP codes
Write a switch expression that maps a status code to a category, grouping several codes per branch.
🧩 Mini-Challenge — Tiny calculator
Only a comment outline is given. Build a calculate method that switches on the operator and guards division by zero with a yield block.
Common Errors
- ❌ Forgetting break in the classic form. Output from several cases appears instead of one. Fix: add break at the end of each case, or switch to the arrow form which has no fall-through.
- ❌ Missing the semicolon on a switch expression. error: ';' expected after the closing brace. A switch expression is assigned to a variable, so it ends with }; — brace and semicolon.
- ❌ Non-exhaustive switch expression. error: the switch expression does not cover all possible input values . Fix: add a default -> branch (or, for enums, cover every constant).
- ❌ Using return instead of yield in a block branch. return would exit the whole method. Fix: use yield value; to return a value from the switch .
- ❌ Switching on a null String. Throws NullPointerException . Fix: check if (s != null) first, or handle null before the switch.
- ❌ Trying to switch on a double or boolean. Not allowed. Switch supports byte, short, char, int, String, and enum only.
Pro Tips
- 💡 Default to the arrow form in new code. It's shorter, safer, and reads as a clean mapping from input to output.
- 💡 Switch on enums, not magic strings, when you can. The compiler then checks you've handled every constant.
- 💡 Keep branches tiny. If a branch grows past a couple of lines, extract a method and call it from the branch.
- 💡 An arrow switch with no default over a complete enum is a feature, not a gap — it forces you to update the switch when you add an enum constant.
📋 Quick Reference
Task
Syntax
Notes
Classic case
case 1: ...; break;
break stops fall-through
Catch-all
default: ...
Runs when nothing matched
Arrow branch
case 1 -> "one";
No break, returns a value
Multiple labels
case 1, 2, 3 -> ...
One branch, several values
Multi-line branch
case X -> { ... yield v; }
yield returns the value
Assign a switch
var r = switch(x) { ... };
Ends with brace + semicolon
❓ Frequently Asked Questions
🎉 Lesson Complete!
You can now write both forms of switch: the classic statement with break and default , and the modern arrow-form expression that returns a value with no fall-through. You understand yield , exhaustive enum switches, and the case-sensitivity of String switches.
Next up: Wrapper Classes & Autoboxing — how Java turns primitives like int into objects like Integer automatically.
Practice quiz
In the classic colon-form switch, what stops execution from falling into the next case?
- continue
- yield
- break
- return
Answer: break. A break statement ends the case; without it, execution falls through.
Consider: int n=2; switch(n){ case 1: print('one'); case 2: print('two'); case 3: print('three'); break; case 4: print('four'); } — what prints?
- two three
- two
- one two three
- three
Answer: two three. It enters at case 2, prints 'two', falls into case 3 printing 'three', then break stops it.
Which symbol marks the modern arrow-form switch branch (Java 14+)?
- : (colon)
- => (fat arrow)
- | (pipe)
- -> (arrow)
Answer: -> (arrow). The arrow form uses 'case X -> ...' with no fall-through.
What is true of the arrow-form switch?
- It needs break statements
- Only the matching branch runs, with no fall-through
- It has fall-through
- It cannot return a value
Answer: Only the matching branch runs, with no fall-through. The arrow form runs only the matching branch and has no fall-through.
Inside a multi-line block branch of a switch expression, how do you return the value?
- yield value;
- return value;
- break value;
- give value;
Answer: yield value;. yield hands a value back from a { } block branch of a switch expression.
A switch expression assigned to a variable must end with...
- just a brace }
- the word end
- a brace and a semicolon };
- a colon
Answer: a brace and a semicolon };. It is an expression assigned to a variable, so it ends with } and a semicolon.
When switching over an enum and covering every constant, do you need a default?
- Yes, always
- No — the compiler proves it is exhaustive
- Only in the colon form
- Only with yield
Answer: No — the compiler proves it is exhaustive. An enum switch covering all constants is exhaustive, so no default is required.
Switching on the String 'STOP' against case "stop" — does it match?
- Yes
- Only with ignoreCase
- It throws
- No, matching is case-sensitive
Answer: No, matching is case-sensitive. String switch matching is case-sensitive, so 'STOP' does not match 'stop'.
Which of these types CANNOT be used in a switch?
- int
- double
- String
- enum
Answer: double. You cannot switch on double (or long, float, boolean); int, String, char, and enum are allowed.
What does an arrow switch expression do that the classic statement does not?
- Run side effects
- Use case labels
- Return a value you can assign
- Have a default
Answer: Return a value you can assign. The arrow form is an expression that returns a value you can assign directly.
Continue this course
- Previous: Enums
- Next: Wrapper Classes & Autoboxing