case
statement is found that matches the value, an optional default statement will be called. If no such default
option is available, the entire switch
statement will be skipped. Notice in Figure 3.3 that case
values can be combined into a single case
statement using commas.
FIGURE 3.3 The structure of a switch
statement
Because switch
statements can be longer than most decision-making statements, the exam may present invalid switch
syntax to see whether you are paying attention.
Combining case Values
Notice something new in Figure 3.3? Starting with Java 14, case
values can now be combined:
switch(animal) { case 1,2: System.out.print("Lion"); case 3: System.out.print("Tiger"); }
Prior to Java 14, the equivalent code would have been the following:
switch(animal) { case 1: case 2: System.out.print("Lion"); case 3: System.out.print("Tiger"); }
As you see shortly, switch
expressions can reduce boilerplate code even more!
See if you can figure out why each of the following switch
statements does not compile:
int month = 5; switch month { // DOES NOT COMPILE case 1: System.out.print("January"); } switch(month) // DOES NOT COMPILE case 1: System.out.print("January"); switch(month) { case 1: 2: System.out.print("January"); // DOES NOT COMPILE }
The first switch
statement does not compile because it is missing parentheses around the switch
variable. The second statement does not compile because it is missing braces around the switch
body. The third statement does not compile because a comma (,
) should be used to separate combined case
statements, not a colon (:
).
One last note you should be aware of for the exam: a switch
statement is not required to contain any case
statements. For example, this statement is perfectly valid:
switch(month) {}
Going back to our printDayOfWeek()
method, we can rewrite it to use a switch
statement instead of if
/else
statements:
public void printDayOfWeek(int day) { switch(day) { case 0: System.out.print("Sunday"); break; case 1: System.out.print("Monday"); break; case 2: System.out.print("Tuesday"); break; case 3: System.out.print("Wednesday"); break; case 4: System.out.print("Thursday"); break; case 5: System.out.print("Friday"); break; case 6: System.out.print("Saturday"); break; default: System.out.print("Invalid value"); break; } }
For simplicity, we just print a message if the value is invalid. If you know about exceptions or have already read Chapter 11, “Exceptions and Localization,” it might make more sense to throw an exception in the default
branch if no match is found.
Exiting with break Statements
Taking a look at our previous printDayOfWeek()
implementation, you'll see a break
statement at the end of each case
and default
section. A break
statement terminates the switch
statement and returns flow control to the enclosing process. Put simply, it ends the switch
statement immediately.
The break
statements are optional, but without them the code will execute every branch following a matching case
statement, including any default
statements it finds. Without break
statements in each branch, the order of case
and default
statements is now extremely important. What do you think the following prints when printSeason(2)
is called?
public void printSeason(int month) { switch(month) { case 1, 2, 3: System.out.print("Winter"); case 4, 5, 6: System.out.print("Spring"); default: System.out.print("Unknown"); case 7, 8, 9: System.out.print("Summer"); case 10, 11, 12: System.out.print("Fall"); } }
It prints everything!
WinterSpringUnknownSummerFall
It matches the first case
statement and executes all of the branches in the order they are found, including the default
statement. It is common, although certainly not required, to use a break
statement after every case
statement.
switch
examples that are missing break
statements! When evaluating switch
statements on the exam, always consider that multiple branches may be visited in a single execution.
Selecting switch Data Types
As shown in Figure 3.3, a switch
statement has a target variable that is not evaluated until runtime. The type of this target can include select primitive data types (int
, byte
, short
, char
) and their associated wrapper classes (Integer
, Byte
, Short
, Character
). The following is a list of all data types supported by switch
statements:
int and Integer
byte and Byte
short and Short
char and Character
String
enum values
var (if the type resolves to one of the preceding types)
For this chapter, you just need to know that an enumeration, or enum, represents a fixed set of constants, such as days of the week, months of the year, and so on. We cover enums in more detail in Chapter 7, including showing how they can define variables, methods, and constructors.
boolean
, long
, float
, and double
are excluded from switch
statements, as are their associated Boolean
, Long
, Float
, and Double
classes. The reasons are varied, such as boolean
having too small a range of values and floating-point numbers having quite a wide range of values. For the exam, though, you just need to know that they are not permitted in switch
statements.
Determining Acceptable Case Values
Not just any variable or value can be used in a case
statement. First, the values in each case
statement must be compile-time constant values of the same data type as the switch
value. This means you can use only literals, enum constants, or final
constant variables of the same data type. By final
constant, we mean that the variable must be marked with the final
modifier and initialized with a literal value in the same expression in which it is declared. For example, you can't have a case
statement value that requires executing a method at runtime, even if that method always returns the same value. For