What you can switch on
int-like types, char, String, enums, and any type with patterns.
What a classic switch accepts
A classic switch works on **byte, short, char, int** (and their wrappers like Integer), **String (since Java 7) and enums. It does not** accept long, float, double or boolean: those need primitive patterns, still a preview feature in Java 25.
long id = 7L;
switch (id) { } // compile error
int n = 7;
switch (n) { } // fineStrings in a switch
The user typed GO. What prints?
String cmd = "GO";
switch (cmd) {
case "go" -> System.out.println("move");
default -> System.out.println("unknown");
}moveunknownmove unknown
Show the answer
unknown. String cases are compared with equals(), which is exact and case-sensitive: "GO" is not "go". A common fix is switch (cmd.toLowerCase()).
What about null?
day is null, and there's a default. What happens?
String day = null;
switch (day) {
case "Sat" -> System.out.println("rest");
default -> System.out.println("work");
}workNothing is printedThrows NullPointerException
Show the answer
NullPointerException. default does not catch null. A switch on a null selector throws unless it has an explicit case null.
Handling a missing value
switch (input) {
case "y" -> accept();
default -> reject();
}If input is null, default never gets a chance: NullPointerException.
switch (input) {
case null -> askAgain();
case "y" -> accept();
default -> reject();
}An explicit case null handles the missing value.
Switching on types (Java 21)
Pattern matching lets switch test the type of any object and bind a variable in one go: case Integer i -> matches when o is an Integer and names it i. A when guard adds an extra condition. Cases are tried top to bottom; the first match wins.
Object o = 42;
String d = switch (o) {
case Integer i -> "int " + i;
case String s -> "text " + s;
default -> "other";
};Guards in action
o holds the Integer 7. What prints?
Object o = 7;
String d = switch (o) {
case Integer i when i > 10 -> "big int";
case Integer i -> "small int";
default -> "other";
};
System.out.println(d);big intsmall intotherCompile error
Show the answer
small int. The first arm matches the type, but its guard i > 10 is false, so Java moves on. The second arm matches with no guard.
In real projects
Command parsers, HTTP methods, event types from JSON: switching on Strings is everywhere. Real input arrives in odd casing and is sometimes missing (null), so production code normalizes the case first and handles null explicitly, or the app crashes on the first weird request.
Key takeaways
- Allowed: byte, short, char, int (and wrappers), String, enums
- Not allowed classically: long, float, double, boolean (primitive patterns are still preview in Java 25)
- String cases compare with equals(), so they're case-sensitive
- A null selector throws NullPointerException unless there's a case null
A switch on Strings is compiled into a switch on each String's hashCode(), followed by equals() checks. That's how it stays fast even with many cases.
Practice questions
Which type can NOT be the selector of a classic switch in Java 25 (without preview features)?
- char
- String
- long
- An enum type
Check your answer
long. Classic switch supports int-sized integer types, their wrappers, String and enums. long, float, double and boolean need primitive patterns, still a preview feature in Java 25.
What does this print?
String cmd = "Stop";
switch (cmd) {
case "stop" -> System.out.println("halt");
case "go" -> System.out.println("move");
default -> System.out.println("unknown");
}- halt
- unknown
- halt unknown
- Compile error
Check your answer
unknown. "Stop" and "stop" differ in case, so no case matches and default runs.