The switch statement

Lesson content

  • What is the switch statement - declaration and elements
  • The break statement
  • Most common errors

What is the switch statement - declaration and elements

The if statement allows conditional branching, i.e., executing one group of commands if a logical condition is satisfied and another group of commands if it is not. This is also known as “single” branching since only two branches are offered (the “YES” branch and the “NO” branch), from which only one is selected and executed.

If it is necessary to check multiple conditions, you can write multiple if statements, each checking one condition. However, the same effect can be achieved using the switch statement. The switch statement allows checking multiple conditions at once and represents a way of expressing “multiple branching” in Java. Multiple branching is such that more alternative branches are offered, from which, depending on the fulfillment of conditions, none, one, or more branches can be executed at once. The declaration of the switch statement is done as follows:

1 switch ( ...selector... ){
2     case value_1:     command_1;
3                       break;
4     case value_2:     command_2;
5                       break;
6     ...
7 
8     default:          command_d;  
9 }

The declaration of the switch statement begins with the reserved keyword switch, followed by the selector written in parentheses. The selector can be any variable of type integer, char, enumerated, or String. Variables of any other type (e.g., double, boolean…) cannot be selectors. The selector can also be an expression whose result is one of the listed types, e.g., “A%2”.

The switch statement also has a body in which all possible branches are defined, and the commands to be executed within the branch. A branch is defined by the reserved word “case” followed by a value. When the switch statement runs, it compares the current value of the selector with the values written after the word case. When a branch is found with a value equal to the selector’s value, the commands written in the body (e.g., command_1) are executed. If no matching branch is found, the default branch is executed, marked with the reserved word default (command_d). The switch statement does not have to have a default branch.

As written, this switch statement represents multiple branching in which only one branch out of several offered is selected and executed. This is exactly the purpose of the break statement, which is written as the last command of each branch. When all commands of a branch are executed, the break command is encountered, which ends the switch statement. If the break statement is omitted, the selected branch would be executed, but also all others written “below” it (including the default branch). A switch statement written this way would represent multiple branching where more than one branch is executed.

Additionally, it is important to note that the commands written within a single branch are not enclosed in curly braces, so the following code is also syntactically correct:

 1 switch ( ...selector... ){
 2     case value_1:     command_1_1;
 3                       command_1_2;
 4                       command_1_3;
 5                       break;
 6     case value_2:     command_2_1;
 7                       command_2_2;
 8                       command_2_3;
 9                       break;
10     ...
11 
12     default:          command_d_1;
13                       command_d_2;
14                       command_d_3;
15 }

Example 1

Create a class DNADecryption which has:

  • A static method decryptDNA which takes as a parameter a character representing the first letter of one of the nucleotides that make up the DNA chain.
    • If the character is ‘A’, ‘C’, ‘G’, or ‘T’, it should print the corresponding nucleotide name that starts with that letter: Adenine, Cytosine, Guanine, and Thymine.
    • If the input character does not have any of those values, print an error message.
 1     class DNADecryption {
 2 
 3         static void decryptDNA(char nucleotide) {
 4             switch (nucleotide) {
 5                 case 'A':
 6                     System.out.println("Adenine");
 7                     break;
 8                 case 'C':
 9                     System.out.println("Cytosine");
10                     break;
11                 case 'G':
12                     System.out.println("Guanine");
13                     break;
14                 case 'T':
15                     System.out.println("Thymine");
16                     break;
17                 default:
18                     System.out.println("Error!");
19             }
20         }
21     }

Create a class TestDNADecryption which in the main method calls the decryptDNA method of the DNADecryption class to decrypt the letter ‘C’.

1 class TestDNADecryption {
2 
3     public static void main(String[] args) {
4         DNADecryption.decryptDNA('C');
5     }
6 }

From this example, it is clear that the switch statement is a possible alternative to multiple if statements, and this is the case here because the condition boils down to the value of the char variable nucleotide.

In this specific case, instead of writing a separate if statement for each DNA nucleotide value and another one for the error case, we have one switch statement. This allows writing slightly more readable code. The alternative code written by using multiple if statements would look like the one as written in the DNADecryptionA class:

 1 class DNADecryptionA {
 2 
 3     static void decryptDNA(char nucleotide) {
 4         if (nucleotide == 'A')
 5             System.out.println("Adenine");
 6         else if (nucleotide == 'C')
 7                 System.out.println("Cytosine");
 8         else if (nucleotide == 'G')
 9                 System.out.println("Guanine");
10         else if (nucleotide == 'T')
11                 System.out.println("Thymine");
12         else System.out.println("Error!");
13     }
14 }

One of the advantages of the switch statement is seen in cases where the same code needs to be executed in multiple branches. In that case, it is enough to write that code in the last branch and omit the break statement.

Example 2

Create a class GradeCheck which has:

  • A static method isPassingGrade that returns false if the grade is 1, and true if the grade is 2, 3, 4, or 5. In all other cases, the method prints “Error” and returns false.
 1     class GradeCheck {
 2 
 3         static boolean isPassingGrade(int grade){
 4             switch (grade){
 5                 case 1: return false;
 6                 case 2:
 7                 case 3:
 8                 case 4:
 9                 case 5: return true;
10                 default: System.out.println("Error");
11                         return false;
12             }
13         }
14     }

Create a class TestGradeCheck which in the main method checks whether the grades 1, 4, and 6 are passing grades.

 1 class TestGradeCheck {
 2 
 3     public static void main(String[] args) {
 4         System.out.println( GradeCheck.isPassingGrade(1) );
 5 
 6         System.out.println( GradeCheck.isPassingGrade(4) );
 7 
 8         System.out.println(GradeCheck.isPassingGrade(6) );
 9     }
10 }

In the code of the isPassingGrade method, it can be seen that the branch for the value 1 is written with a command to return false and without the break statement. This is fine because the return statement will terminate the method anyway. After that, the branches for the values 2, 3, and 4 are written without commands, but also without the break statement, so in the case of grades 2, 3, or 4, all commands will be executed, including the branch for the value 5 - which will return true.

The default branch will execute if the method is not terminated by the previous branches, i.e., if the entered grade is not within the range of 1 to 5. In this branch, in addition to printing the “Error” message, it is necessary to return a boolean value (false), as the method is expected to return some boolean value in every case.

Finally, the SWITCH statement is often used in practice with enumerated types, where the branches of the SWITCH statement correspond to instances of an enumerated type.

Example 3

Create an enumerated type OrderStatus which has instances:

  • DELIVERED, IN_TRANSPORT, CANCELLED, LOST
1     enum OrderStatus {
2         DELIVERED,
3         IN_TRANSPORT,
4         CANCELLED,
5         LOST;
6     }

Create a class OrderClaimProcessor which has:

  • A static method resolveOrderClaim which takes the order status (enumerated type) as a parameter and prints a suggestion on how to resolve the order claim:
    • If the status is DELIVERED or CANCELLED, print “No action needed”
    • If the status is LOST, print “Pay compensation to the sender”
    • If the status is IN_TRANSPORT, print “Wait another two days”
 1     class OrderClaimProcessor {
 2 
 3         static void resolveOrderClaim(OrderStatus status){
 4             switch (status){
 5                 case DELIVERED:
 6                 case CANCELLED:
 7                     System.out.println("No action needed");
 8                     break;
 9                 case LOST:
10                     System.out.println("Pay compensation to the sender");
11                     break;
12                 case IN_TRANSPORT:
13                     System.out.println("Wait another two days");
14             }
15         }
16     }

Create a class TestOrderClaimProcessor which in the main method resolves an order claim with the status IN_TRANSPORT.

1 class TestOrderClaimProcessor {
2 
3     public static void main(String[] args) {
4         OrderClaimProcessor.resolveOrderClaim(OrderStatus.IN_TRANSPORT);
5     }
6 }

Here, the branches for the statuses DELIVERED and CANCELLED are “merged”. However, the break statement is necessary as the last statement in each branch to terminate the SWITCH statement. This does not need to be done in the last branch (for the IN_TRANSPORT status) because it is the last branch and there are no further commands after it.

Most common errors

Some of the most common syntax errors related to writing the switch statement include:

  • Specifying a variable as a selector, but it is not of type char, integer, String, or an enumerated type.

  • Writing a logical condition within the selector instead of specifying a char, integer, String, or enumerated variable, or an expression that returns a char, integer, String, or enumerated value.

 1     switch (day <= 5){
 2       case 1:
 3       case 2:
 4       case 3:
 5       case 4:
 6       case 5:
 7         System.out.println("Weekday");
 8         break;
 9       case 6:
10       case 7:
11         System.out.println("Weekend");
12     }

Instead (correct version):

 1     switch (day){
 2       case 1:
 3       case 2:
 4       case 3:
 5       case 4:
 6       case 5:
 7         System.out.println("Weekday");
 8         break;
 9       case 6:
10       case 7:
11         System.out.println("Weekend");
12     }
  • Writing the same value of the selector on multiple branches:
 1     switch (day){
 2       case 1:
 3       case 1:
 4       case 2:
 5       case 3:
 6       case 4:
 7       case 4:
 8       case 5:
 9         System.out.println("Weekday");
10         break;
11       case 6:
12       case 7:
13         System.out.println("Weekend");
14     }

Instead (correct version):

 1     switch (day){
 2       case 1:
 3       case 2:
 4       case 3:
 5       case 4:
 6       case 5:
 7         System.out.println("Weekday");
 8         break;
 9       case 6:
10       case 7:
11         System.out.println("Weekend");
12     }
  • Forgetting to write a return statement in each branch of the switch statement, as well as in the default branch, so that the method always returns a value.
 1     switch (day){
 2       case 1:
 3       case 2:
 4       case 3:
 5       case 4:
 6       case 5:
 7         return true;
 8       case 6:
 9       case 7:
10         return false;
11     }

Instead (correct version), with a default branch which is mandatory here:

 1     switch (day){
 2       case 1:
 3       case 2:
 4       case 3:
 5       case 4:
 6       case 5:
 7         return true;
 8       case 6:
 9       case 7:
10         return false;
11       default:
12         return false;
13     }

Other common non-syntax errors that affect program behavior:

  • Forgetting to put the break statement as the last command in each branch (if there is no return statement to terminate the SWITCH statement).
 1     switch (day){
 2       case 1:
 3         System.out.print("Monday");
 4       case 2:
 5         System.out.print("Tuesday");
 6       case 3:
 7         System.out.print("Wednesday");
 8       case 4:
 9         System.out.print("Thursday");
10       case 5:
11         System.out.print("Friday");
12       case 6:
13         System.out.print("Saturday");
14       case 7:
15         System.out.print("Sunday");
16     }

Instead (correct version):

 1     switch (day){
 2       case 1:
 3         System.out.print("Monday");
 4         break;
 5       case 2:
 6         System.out.print("Tuesday");
 7         break;
 8       case 3:
 9         System.out.print("Wednesday");
10         break;
11       case 4:
12         System.out.print("Thursday");
13         break;
14       case 5:
15         System.out.print("Friday");
16         break;
17       case 6:
18         System.out.print("Saturday");
19         break;
20       case 7:
21         System.out.print("Sunday");
22     }
  • If multiple branches have the same commands, placing those commands (by mistake) only in the first one, not in the last one.
 1     switch (continent){
 2         case NORTH_AMERICA:
 3             System.out.println("Northern Hemisphere");
 4             break;
 5         case EUROPE:
 6         case AUSTRALIA:
 7             System.out.println("Southern Hemisphere");
 8             break;
 9         case ANTARCTICA:
10         case SOUTH_AMERICA:
11             System.out.println("Both Hemispheres");
12         case ASIA:
13         case AFRICA:
14     }

Instead (correct version):

 1     switch (continent){
 2         case EUROPE:
 3         case NORTH_AMERICA:
 4             System.out.println("Northern Hemisphere");
 5             break;
 6         case ANTARCTICA:
 7         case AUSTRALIA:
 8             System.out.println("Southern Hemisphere");
 9             break;
10         case ASIA:
11         case AFRICA:
12         case SOUTH_AMERICA:
13             System.out.println("Both Hemispheres");
14     }