15

Why java switch statement can't handle null, since it has a "default" clause?

For example, if you have something like

   switch(value){
     case VAL1: do_something1(); break;
     case VAL2: do_something2(); break;
     default: do_something3(); 
   }

shouldn't "default" deal with any other value, such as null?

  • 3
    as of 1.7(i think) it handles strings, but it only ever used to handle enums/ints, so maybe there's some legacy in there which won't allow nulls still. I'm sure somebody will know why – Rich Nov 12 '13 at 14:13
  • 1
    In fact it would be interesting to know the real reasons (the one we all see in the JLS is really dubious). – Denys Séguret Nov 12 '13 at 14:20

4 Answers4

14

As always, it's in the JLS:

14.11. The switch Statement

All of the following must be true, or a compile-time error occurs:

  • ...
  • No switch label is null.

...
The prohibition against using null as a switch label prevents one from writing code that can never be executed. If the switch 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 to null at run time. In the judgment of the designers of the Java programming language, this is a better outcome than silently skipping the entire switch statement or choosing to execute the statements (if any) after the default label (if any).

Community
  • 1
  • 1
Matt Ball
  • 354,903
  • 100
  • 647
  • 710
12

In short, this design choice is in the spirit of Java.

The decision to throw an NPE when a switch expression evaluates to null is along the lines of other decisions made in Java, which always prefer throwing an exception to silently handling the null in the "obvious" way. The general rule seems to be that, when in doubt, the Java designers choose the option without default behavior. This has the side-effect of requiring boilerplate code at every use site.

Some would call this frustrating and unfortunate, but others disagree, maintaining that this is a safer decision.

For another potentially frustrating example see the enchanced for loop, which also throws an NPE if the collection is null, instead of acting as if the collection was empty. There are many more examples in the JDK library, where the caller must check all edge cases just to be allowed to treat them uniformly with the "normal" cases.

As a third notorious example, Java's checked exceptions require a lot of boilerplate to handle at every level of call stack depth, and lure less experienced programmers into several antipatterns. The results are often swallowed exceptions, the same exception being reported several times in the log, exceptions getting non-uniform handling at the wrong level of abstraction, etc.

Marko Topolnik
  • 195,646
  • 29
  • 319
  • 436
  • I don't think the argument for NPEs is really "safer" but to facilitate a fail fast mentality, which makes errors many times easier to debug than swallowing errors. You could also argue, that you should strive to not expect null in your code. – Patrick Jan 28 '20 at 09:36
1

You can't SWITCH on strings and other data types that can be null. This behaviour has been changed in Java 7 to allow string-switches.

See this question for more info:

Why can't I switch on a String?

Community
  • 1
  • 1
davek
  • 22,499
  • 9
  • 75
  • 95
1

This is by definition. I wouldn't lose too much time on this as it's in the specifications.

On the other hand I find this quite practical in fact, as in case of being null it doesn' have a primitive type associated, so we can't know how to handle it properly.

Alex
  • 975
  • 10
  • 24