Why is this such an insidious error in Java? (An opinion piece!)
Firstly, I’ll show a short comparison between some Java code and some code from a language that doesn’t have
NullPointerExceptions, but does have something that allows you to accomplish anything you might want to do with null pointers.
This Java code:
AnObject thing = someMethod();
is equivalent to the following Haskell:
let thing = Maybe AnObject
That is, every Java object reference is possibly null. What this means is that (using the type notation mentioned in earlier posts) every Java reference has the type:
(Every object reference for an object is either to ‘null’ (AKA ‘unit’ or ‘singleton’, or the object itself.)
… and when you’re dealing with so many objects—Java is, after all, an object-oriented language, so (almost) everything is an object—this simple little “+1″ gets lost easily.
Why so bad?
This wouldn’t seem to be such a big deal, but when contrasted against Java’s penchant for making things (sometimes painfully) explicit—think
public static void main (string argh!)—a small, implicit item like this is easily overlooked. Conversely, one might say that the verbosity of Java increases the cognitive load of understanding its code; thus helping the chances of a small mistake like this sneaking through.
Either way, I think I can say that this is objectively A Bad Thing. C# has gone some of the way to a ‘correct’ solution in its introduction of possibly-null primitives, which are explicitly marked with a
? (such as
int?), but unfortunately this hasn’t been ‘back-ported’ to the rest of the language. If one were able to force between possibly-null and definitely-not-null references in C#—perhaps by the analogous
object, this would help to reduce the number of errors ‘hidden’ by the syntax.