In Java a switch
acts upon a variable and selects the case
-statement that matches. Switch has limits, but has also advantages and elegance.
In a switch
, control flow falls through to the next case. We must be careful to use breaks (or returns) to prevent incorrect behavior.
We loop over the number range 0 through 2 inclusive with a for
-loop. On each integer, we use a switch
statement.
switch
has no case for 0, so the default block is reached. We print out a message to the console with System.out
.break
exits the switch
statement at the end of case 1, and then the loop continues.break
occurs, so it then matches default.public class Program { public static void main(String[] args) { // Loop through 0, 1, and 2. for (int i = 0; i <= 2; i++) { // Switch on number. switch (i) { case 1: { System.out.println("One: " + i); break; } case 2: case 3: { System.out.println("Two or three: " + i); } default: { System.out.println("Default case: " + i); } } } } }Default case: 0 One: 1 Two or three: 2 Default case: 2
String
switch
This program uses String
literals within a switch
-statement. If we pass "Max
" or "Elle" to getValue
, these literals are detected. We return from the switch
statement.
public class Program { static int getValue(String name) { // Switch on a String argument. switch (name) { case "Max": return 1; case "Elle": return 2; } return 0; } public static void main(String[] args) { // Call method that uses switch. String name = "Max"; int result = getValue(name); System.out.println(result); System.out.println(getValue("Elle")); } }1 2
switch
We sometimes nest a switch
within another one. This program uses two switches. It first checks the first letter of a string
(with charAt
) and then tests the second char
.
string
matches this way. A switch
can check all possible characters at each position.public class Program { public static void main(String[] args) { String value = "hi"; // Switch on first letter. switch (value.charAt(0)) { case 'h': // Switch on second letter. switch (value.charAt(1)) { case 'i': System.out.println("Values are h, i"); break; case 'e': System.out.println("?"); break; } break; case 'e': System.out.println("?"); break; } } }Values are h, i
A switch
cannot have variables in its cases. It must have constants. But we can use compile-time, constant expressions as cases. This can make code clearer.
public class Program { public static void main(String[] args) { int value = 100; // Match constant-value expressions in cases. switch (value) { case 10 * 1: System.out.println("A"); break; case 10 * 10: System.out.println("B"); break; case 10 * 100: System.out.println("C"); break; } } }B
A switch
cannot have duplicate cases. This error sometimes occur in large switches that are harder to remember. The program does not compile.
public class Program { public static void main(String[] args) { int value = 100; // This switch causes compilation problems. switch (value) { case 100: System.out.println(true); break; case 100: System.out.println(true); break; } } }Exception in thread "main" java.lang.Error: Unresolved compilation problems: Duplicate case Duplicate case at program.Program.main(Program.java:9)
Cases in a switch
must match the type of the value being switched upon. Java provides this checking to ensure program quality—switch
cases are valid based on the type.
public class Program { public static void main(String[] args) { byte value = 100; // A byte can never equal 1000 so an error occurs. switch (value) { case 1000: System.out.println(false); return; } } }Exception in thread "main" java.lang.Error: Unresolved compilation problem: Type mismatch: cannot convert from int to byte at program.Program.main(Program.java:8)
Statements like continue and return can be used within a switch
. But these affect the enclosing block, not the switch
itself.
switch
moves to the next iteration in an enclosing loop. A return acts on the enclosing method.public class Program { public static void main(String[] args) { for (int i = 0; i < 5; i++) { switch (i) { case 0: case 1: // The continue moves to the next iteration in the loop. continue; default: // This breaks the switch, not the loop. break; } System.out.println(i); } } }2 3 4
switch
Switch sometimes has clear performance advantages over an if
-statement. Consider this example. The values 0 through 4 are tested many times.
switch
-statement to test for the values 0 through 4.if-else
chain to test for the values 0 through 4. We can use more complex expressions here.switch
statement is faster. But switch
can slow down a method—try checking for the most common case in an if
-statement.public class Program { public static void main(String[] args) { long t1 = System.currentTimeMillis(); // Version 1: use switch. int total = 0; for (int i = 0; i < 100000000; i++) { switch (i) { case 0: total--; break; case 1: total -= 2; break; case 2: case 3: case 4: total++; break; } } long t2 = System.currentTimeMillis(); // Version 2: use if-else. int total2 = 0; for (int i = 0; i < 100000000; i++) { if (i == 0) { total2--; } else if (i == 1) { total2 -= 2; } else if (i >= 2 && i <= 4) { total2++; } } long t3 = System.currentTimeMillis(); // ... Times. System.out.println(t2 - t1); System.out.println(t3 - t2); } }234 ms, switch 281 ms, if/else if
We use switch
to rewrite, and clarify, this code. We benchmarked and tested this construct. Switch supports Strings and constant expressions.