Java switch selects behavior using one value. A switch statement executes a matching branch, while a switch expression produces a value that can initialize a variable or be returned from a method. Modern arrow cases make many simple choices clearer because they do not fall through into the next case.
This lesson uses Java 17 without preview features. Integer, String and enum selectors are enough to learn the core behavior. Pattern matching in switch is a separate modern feature with different version requirements; do not mix its rules into ordinary beginner examples.
Choose switch for one discrete selector
A switch is useful when one selector determines among a finite set of alternatives: a menu choice, status code or direction. For this Java 17 lesson, familiar selectors include int, String and enum values. Traditional switch also supports byte, short and char and the corresponding eligible wrapper types. It does not accept boolean, long, float or double as an ordinary selector.
Use if-else when the decision involves ranges, unrelated conditions or several variables. For example, temperature < 0 and temperature > 30 are not ordinary discrete case labels. A String switch matches string content, with case-sensitive matching. A null String selector throws NullPointerException in these ordinary Java 17 forms, so validate a nullable selector before switching.
Traditional cases can fall through
A colon-style case marks a position inside the switch. After entering at the matching label, execution continues through later statements and labels unless a break, return, throw or other control transfer stops it. A break exits the switch; it does not merely end the current source line.
Fall-through can group several labels for the same action, but missing a required break is a common bug. Add an explanatory comment for intentional fall-through if the structure is not obvious. default supplies a branch when no case matches. A statement can omit default and perform no matching action, but an explicit response is often clearer when a user can supply an unsupported menu choice.
Arrow cases do not fall through
An arrow case uses case value -> action. After its action finishes, execution does not continue into the next case. Several constant labels can share one arrow rule, such as case 1, 2 -> "weekday"; in an appropriate expression. If an action needs several statements, use a block after the arrow.
Arrow labels are available for both switch statements and switch expressions. Their presence alone does not mean the switch produces a value. A statement might print a selected message, whereas an expression might assign that selected message to a variable. Keep the intended role clear from the surrounding syntax. Do not mix colon-style labels and arrow-style rules within the same switch block.
A switch expression must produce a result
A switch expression evaluates to a value. Its alternatives must cover the possible selectors, normally with default for an int or String selector. An enum expression can be exhaustive by naming every enum constant. Each selected branch must yield a value or complete abruptly, such as by throwing an exception.
With a simple arrow expression, the branch value follows the arrow. With a block containing calculations, use yield to provide the switch expression’s result. yield is not a method return: it exits that switch expression with a value, after which the surrounding method continues. An assignment containing a switch expression ends with a semicolon, because the entire declaration or assignment is still a statement.
Defaults, enums and input boundaries
A default can return a fallback description or reject an unsupported value, depending on the program’s contract. Avoid a silent fallback when an invalid value should be visible to the caller. For a menu, an Unknown choice message can be useful; for a configuration that must be valid, throwing an exception may be more appropriate.
Enum selectors are convenient when the valid alternatives are a controlled vocabulary. Covering all constants makes the expression’s intended scope visible. Adding a new enum constant may require revisiting the selection. For external String input, decide whether to normalize case or whitespace before switching, and preserve that decision consistently. switch itself does not trim strings, parse numbers or check user permissions.
Practice with explained solutions
Task 1. Write a switch expression mapping "small" to 1, "large" to 3 and every other value to 0.
Solution. Use arrow expressions and a default, assign the result to an int variable, and terminate the declaration with a semicolon.
Task 2. Explain what happens after a colon-style matching case prints text but has no break before the next case.
Solution. Execution continues into subsequent statements. The next case label is not automatically a stopping boundary. Add break unless the fall-through is intentional.
Java Summary
- Arrow rules do not fall through; traditional colon cases need deliberate exit control.
- A switch expression must produce a result or complete abruptly for every permitted selection.
- Use yield for a calculated result inside an expression branch.
- Continue with nested conditions.
Java Examples
Each example shows the code, the output it produces and what each part does.
A selected statement
Save this complete program as MenuSelection.java. Compile with javac --release 17 MenuSelection.java and run with java MenuSelection.
public class MenuSelection {
public static void main(String[] args) {
int choice = 2;
switch (choice) {
case 1 -> System.out.println("Open");
case 2 -> System.out.println("Save");
default -> System.out.println("Unknown choice");
}
}
}SaveLine-by-line explanation
- Lines 1 to 10The selector evaluates to two, so Java runs only the matching arrow rule. Its println prints Save, and no other branch executes. This is a switch statement because its purpose is the selected action rather than a returned value. Set choice to seven to see the default response, which makes unsupported input visible instead of silently performing nothing.
Assign the result of an expression
Save this complete program as DayLabel.java. Compile with javac --release 17 DayLabel.java and run with java DayLabel.
public class DayLabel {
public static void main(String[] args) {
int day = 6;
String label = switch (day) {
case 1, 2, 3, 4, 5 -> "Weekday";
case 6, 7 -> "Weekend";
default -> "Invalid day";
};
System.out.println(label);
}
}WeekendLine-by-line explanation
- Lines 1 to 11The expression selects Weekend and initializes label with that value. Grouping six and seven under one arrow avoids duplicating the result. The semicolon after the closing brace finishes the variable declaration. Java cannot use the printed output of a statement as this initializer; the switch must actually produce a value.
Use yield after branch calculations
Save this complete program as DeliveryCharge.java. Compile with javac --release 17 DeliveryCharge.java and run with java DeliveryCharge.
public class DeliveryCharge {
public static void main(String[] args) {
String speed = "express";
int charge = switch (speed) {
case "express" -> {
int base = 5;
int surcharge = 3;
yield base + surcharge;
}
case "standard" -> 5;
default -> 0;
};
System.out.println(charge);
}
}8Line-by-line explanation
- Lines 1 to 8The express block calculates two local values and yields their sum. That eight becomes the value of the switch expression and initializes charge.
- Lines 9 to 15The later println still executes, proving yield did not return from main. The zero fallback is merely this example’s stated policy; a real checkout may reject an unknown speed instead of treating it as free shipping.
Common Java Mistakes
Using break where a switch expression needs a value
Do not put break where a switch expression requires a value. Use yield inside a result-producing block. In a traditional colon-style statement, check whether a missing break permits unintended fall-through. Also do not copy a pattern-switch example from a newer Java version into this Java 17 lesson without checking its language requirements.
Java FAQ
Are switch expressions available in Java 17?
Yes. They became a permanent language feature in Java 14 and need no preview flags here.
Can switch replace every if statement?
No. Ordinary switch is best for discrete alternatives based on one selector. Ranges and unrelated conditions are usually clearer with if-else.
Can a switch expression throw an exception instead of returning a value?
Yes. A case can end with throw, as in default -> throw new IllegalArgumentException("Unknown size: " + size);. This is the clearest way to reject unsupported values, because the switch still produces a value for every valid input.
Can I mix arrow cases and colon cases in one switch?
No. A single switch uses one style throughout; mixing them gives the error "different case kinds used in the switch". Choose arrow cases for new code, and colon cases with yield only where fall-through between labels is genuinely needed.
Does the order of cases matter in a switch?
For constant labels, no: each value matches at most one case, so you can order them for readability. For type patterns with when guards in newer Java versions, order matters, because the first matching case wins and the compiler rejects a case that an earlier one fully covers.
Java Exercises
Answer each one and check it instantly. If you get stuck, open the hint before the answer.
What happens after selecting case 6, 7 -> "Weekend"?
What does yield end in DeliveryCharge?
Java Quiz
2 questions to check what you learned.
Which keyword supplies a value from a switch-expression block?
- yield
- continue
- package
Do arrow rules fall through automatically?
- No
- Yes
- Only when printing