Why doesn't String switch statement support a null case?
As damryfbfnetsi points out in the comments, JLS §14.11 has the following note:
The prohibition against using
null
as a switch label prevents one from writing code that can never be executed. If theswitch
expression is of a reference type, that is,String
or a boxed primitive type or an enum type, then a run-time error will occur if the expression evaluates tonull
at run time. In the judgment of the designers of the Java programming language, this is a better outcome than silently skipping the entireswitch
statement or choosing to execute the statements (if any) after thedefault
label (if any).
(emphasis mine)
While the last sentence skips over the possibility of using case null:
, it seems reasonable and offers a view into the language designers' intentions.
If we rather look at implementation details, this blog post by Christian Hujer has some insightful speculation about why null
isn't allowed in switches (although it centers on the enum
switch rather than the String
switch):
Under the hood, the
switch
statement will typically compile to a tablesswitch byte code. And the "physical" argument toswitch
as well as its cases areint
s. The int value to switch on is determined by invoking the methodEnum.ordinal()
. The [...] ordinals start at zero.That means, mapping
null
to0
wouldn't be a good idea. A switch on the first enum value would be indistinguishible from null. Maybe it would've been a good idea to start counting the ordinals for enums at 1. However it hasn't been defined like that, and this definition can not be changed.
While String
switches are implemented differently, the enum
switch came first and set the precedent for how switching on a reference type should behave when the reference is null
.
In general null
is nasty to handle; maybe a better language can live without null
.
Your problem might be solved by
switch(month==null?"":month)
{
...
//case "":
default:
monthNumber = 0;
}
It isn't pretty, but String.valueOf()
allows you to use a null String in a switch. If it finds null
, it converts it to "null"
, otherwise it just returns the same String you passed it. If you don't handle "null"
explicitly, then it will go to default
. The only caveat is that there is no way of distinguishing between the String "null"
and an actual null
variable.
String month = null;
switch (String.valueOf(month)) {
case "january":
monthNumber = 1;
break;
case "february":
monthNumber = 2;
break;
case "march":
monthNumber = 3;
break;
case "null":
monthNumber = -1;
break;
default:
monthNumber = 0;
break;
}
return monthNumber;