Switch Statement
A powerful control flow statement in Java, the switch statement gives your application the ability to select from a variety of execution pathways. For multiway branching, it provides an alternative to lengthy if-then-else if statements, frequently producing more legible and effective code.
Typically, program statements are run in the order they appear, from top to bottom. Nevertheless, your program can conditionally run specific code blocks based on branching, looping, or decision-making thanks to control flow instructions like switch.
A switch statement evaluates an expression and then executes all statements that follow the matching case label.
Supported Data Types: A switch statement can be controlled by an expression that contains a variety of data kinds, including:
- Primitive data types:
byte,short,char, andint. - Enumerated types (
enum). - The
Stringclass. - Wrapper classes for certain primitive types:
Character,Byte,Short, andInteger.
Components of a Statement
The body of a switch statement is known as a switch block. Inside this block, statements can be labelled with case or default labels.
Labels
- A
caselabel specifies a constant value that theswitchexpression is compared against for equality. - Each
valuespecified in thecasestatements must be a unique literal (a constant, not a variable), and its type must be compatible with theswitchexpression’s type. - Multiple
caselabels can be used to execute the same code block if several values should trigger the same action. This is common when several cases share common code.
Statement
- The
breakstatement is crucial inswitchstatements as it terminates the enclosing switch statement. - When a
breakstatement is encountered, control flow continues with the first statement following the switch block. - Without
breakstatements, statements inswitchblocks will “fall through”. This means all statements after the matchingcaselabel are executed in sequence, regardless of subsequentcaselabels, until abreakstatement is encountered. - While
breakis technically optional, using it is highly recommended to prevent unintended fall-through, make code modification easier, and reduce errors. If you omit thebreak, execution will continue into the nextcase.
Here’s an example demonstrating break in a switch statement:
public class SwitchDemo {
public static void main(String[] args) {
int month = 8;
String monthString;
switch (month) {
case 1: monthString = "January";
break;
case 2: monthString = "February";
break;
case 3: monthString = "March";
break;
case 4: monthString = "April";
break;
case 5: monthString = "May";
break;
case 6: monthString = "June";
break;
case 7: monthString = "July";
break;
case 8: monthString = "August";
break;
case 9: monthString = "September";
break;
case 10: monthString = "October";
break;
case 11: monthString = "November";
break;
case 12: monthString = "December";
break;
default: monthString = "Invalid month";
break; // Final break is technically not required but recommended
}
System.out.println(monthString);
}
}
Output:
August
To illustrate fall-through without break statements:
public class SwitchDemoFallThrough {
public static void main(String[] args) {
java.util.ArrayList<String> futureMonths =
new java.util.ArrayList<String>();
int month = 8;
switch (month) {
case 1: futureMonths.add("January");
case 2: futureMonths.add("February");
case 3: futureMonths.add("March");
case 4: futureMonths.add("April");
case 5: futureMonths.add("May");
case 6: futureMonths.add("June");
case 7: futureMonths.add("July");
case 8: futureMonths.add("August"); // Execution starts here
case 9: futureMonths.add("September");
case 10: futureMonths.add("October");
case 11: futureMonths.add("November");
case 12: futureMonths.add("December");
break; // Break stops further fall-through
default: break;
}
if (futureMonths.isEmpty()) {
System.out.println("Invalid month number");
} else {
for (String monthName : futureMonths) {
System.out.println(monthName);
}
}
}
}
Output:
August
September
October
November
December
As you can observe, because the break statements were omitted from case 1 through case 7, execution falls through from case 8 and continues adding months to the futureMonths list until it reaches the break statement after case 12.
Label
- The
defaultsection is an optional part of theswitchstatement. - It handles all values that are not explicitly covered by any of the
casesections. If nocasematches theswitchexpression’s value and nodefaultis present, then no action will take place. - No
breakis strictly needed in thedefaultcase if it’s the last option, as control flow naturally exits theswitchblock.
Using in Statements (JDK 7+)
From JDK 7 onwards, you can utilize a String object in the expression of the switch statement. When this functionality is used instead of a string of if/else statements, it can greatly simplify some programming scenarios and enhance code readability.
Comparison Mechanism: Comparing a String in a switch expression with the expressions linked to each case label is done as though the String.equals() method were being utilized. This suggests that the comparison is automatically case-sensitive.
Case-Insensitivity: Before the switch expression, you should use the toLowerCase() or toUpperCase() methods to change the String to lowercase or uppercase in order to accomplish case-insensitive comparison with strings in a switch statement. Then, each case label ought to be in the appropriate case as well.
NullPointerException Warning: It is important to make sure that any switch statement’s String expression is not null. At runtime, a NullPointerException will be raised if the String expression is null.
Efficiency Consideration: Although convenient, turning on strings may not be as efficient as turning on numbers. In order to improve readability, it is therefore recommended to utilize Strings in a switch only when the controlling data is already in String form.
Here’s an example using a String in a switch statement:
public class StringSwitchDemo {
public static int getMonthNumber(String month) {
int monthNumber = 0;
if (month == null) { // Important: check for null to prevent NullPointerException
return monthNumber;
}
switch (month.toLowerCase()) { // Convert to lowercase for case-insensitivity
case "january": monthNumber = 1; break;
case "february": monthNumber = 2; break;
case "march": monthNumber = 3; break;
case "april": monthNumber = 4; break;
case "may": monthNumber = 5; break;
case "june": monthNumber = 6; break;
case "july": monthNumber = 7; break;
case "august": monthNumber = 8; break;
case "september": monthNumber = 9; break;
case "october": monthNumber = 10; break;
case "november": monthNumber = 11; break;
case "december": monthNumber = 12; break;
default: monthNumber = 0; break;
}
return monthNumber;
}
public static void main(String[] args) {
String month = "August";
int returnedMonthNumber = StringSwitchDemo.getMonthNumber(month);
if (returnedMonthNumber == 0) {
System.out.println("Invalid month");
} else {
System.out.println(returnedMonthNumber);
}
// Example with a different case
month = "january";
returnedMonthNumber = StringSwitchDemo.getMonthNumber(month);
System.out.println(returnedMonthNumber);
// Example with null input (will handle gracefully due to null check)
month = null;
returnedMonthNumber = StringSwitchDemo.getMonthNumber(month);
System.out.println(returnedMonthNumber);
}
}
Output for the above code:
8
1
0
if-then-else vs switch statement
The choice between a switch statement and an if-then-else statement frequently comes down to readability and the kind of expression being examined.
An if-then-else statements can test phrases that depend on complex criteria or ranges of values.
A switch statement, on the other hand, expressly checks for equality and evaluates expressions based on a single integer, enumerated value, or String object. Switch statements typically execute faster because of compiler optimizations like “jump tables” when you need to choose from a broad set of values based on equality.
