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
String
class. - 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
case
label specifies a constant value that theswitch
expression is compared against for equality. - Each
value
specified in thecase
statements must be a unique literal (a constant, not a variable), and its type must be compatible with theswitch
expression’s type. - Multiple
case
labels 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
break
statement is crucial inswitch
statements as it terminates the enclosing switch statement. - When a
break
statement is encountered, control flow continues with the first statement following the switch block. - Without
break
statements, statements inswitch
blocks will “fall through”. This means all statements after the matchingcase
label are executed in sequence, regardless of subsequentcase
labels, until abreak
statement is encountered. - While
break
is 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
default
section is an optional part of theswitch
statement. - It handles all values that are not explicitly covered by any of the
case
sections. If nocase
matches theswitch
expression’s value and nodefault
is present, then no action will take place. - No
break
is strictly needed in thedefault
case if it’s the last option, as control flow naturally exits theswitch
block.
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.