switch and break
An else if chain suits different questions. But when one variable is compared against a long list of values, the chain repeats the same thing: light == 'g', then light == 'y', then once more. For that kind of choice Java has the switch statement.
Picture a corridor with a row of doors. Each door has a value written on it: 'g', 'y'. switch looks once at what the variable holds and opens the door with the same value. But the rooms behind the doors are connected by passages: from your room you can walk into the next one, and from there further on. Only an exit to the outside stops you, and that exit is called break.
Here is a traffic light written with switch:
public class Main {
public static void main(String[] args) {
char light = 'y';
switch (light) {
case 'g':
System.out.println("go");
break;
case 'y':
System.out.println("wait"); // wait
break;
default:
System.out.println("stop");
}
}
}Let's walk through the program:
char light = 'y';: the light is yellow.switch (light)takes the value oflightonce and looks for the doorcase 'y'.case 'g':does not match, and the program skips its code.case 'y':matches: the program enters here and printswait.breakleaves theswitch, so thedefaultcode does not run.
The parts of a switch
Inside the braces of a switch there are three kinds of parts.
case
case 'y': is called a label. It is a door with a sign on it:
- after
casecome a value and a colon; - the value is a constant that fits the type of the variable in the
switchparentheses; - one value cannot stand on two doors: the compiler answers
duplicate case label.
The branch's code goes after the label, usually on the following lines.
break
break is the exit to the outside. Execution jumps straight to the first statement after the closing brace of the switch.
default
The default label is the door for every other value. Its code runs when no case matched. In the example that is any light other than green and yellow. Without default, nothing runs in that case.
Fall-through
What happens if you forget break? Execution does not stop at the end of the branch. It moves on to the code of the next label and runs it without comparing the value. This is called fall-through.
The widget shows the same traffic light: the light is green, and the break after go is gone. Press "Next step" and watch which lines run after go.
1public class Main {2 public static void main(String[] args) {3 char light = 'g';4 switch (light) {5 case 'g':6 System.out.println("go");7 case 'y':8 System.out.println("wait");9 break;10 default:11 System.out.println("stop");12 }13 System.out.println("done");14 }15}
The variable light holds the character g: the light is green.
Fall-through continues until the first break or the end of the switch. The default label is no protection: if execution reaches it through a passage, its code runs too.
Here the corridor is inexact in one way. A person decides whether to walk into the next room. Java does not decide: it keeps going until it meets a break. Interviewers like to show a switch without break and ask what it prints.
Fall-through on purpose
Sometimes fall-through is useful: several values lead to the same code. Then the labels go one after another, with no code between them:
String day = "sun";
switch (day) {
case "sat":
case "sun":
System.out.println("weekend"); // weekend
break;
default:
System.out.println("workday");
}day equals "sun", and execution enters at the label case "sun":. If day were "sat", it would enter at the label above and fall through to the same code. The same two values can also be written as one label with a comma: case "sat", "sun":.
Which values fit
switch does not work with every type:
- the whole-number types
int,short,byteand the character typecharfit; Stringfits: the labelcase "sun"matches when the string sayssun;long,double,floatandbooleando not fit.
Common mistake
The break was forgotten in the last branch before default:
int choice = 1;
switch (choice) {
case 1:
System.out.println("play"); // ✗
default:
System.out.println("no such item");
}The program prints two lines: play and no such item. The label case 1 matched, the branch has no break, and execution fell through into default. The compiler accepts this program with no error: javac prints the warning possible fall-through into case only with the -Xlint:all flag. Put a break after the first println, and default will fire only for an unknown menu item.
Key points
switchevaluates the value once and jumps to thecaselabel with the same value.breakleaves theswitch; without it, execution falls through into the next branches without checking their labels.defaultruns when nocasematched, or when fall-through reaches it.- A classic
switchworks withint,charandString, but not withlong,doubleorboolean.