Null is Not an Exception

When I first learned how to program, object oriented tools didn'texist. Instead for years procedural programming was all I had. As a result my "object-oriented" code tends to smack of procedural code quite often and I have to re-factor to optimize for re-use, modularity and testing.

So it comes as no surprise that post procedural programmers like myself will sprinkle their Java code with poor usage patterns that hark back to earlier days. One example is the absence of proper exception throws. More specifically, using null as an acceptable error condition.

When coding in say C, the programmer will return a particular numerical error code from a function if something was amiss during execution. The calling function was then fit to deal with the error code as it saw fit. This worked but was problematic as the codes were only visible at runtime and only had context if there was a list to match these codes. Those of you who program in Microsoft ASP code and see meaningless error codes such as 502345 know what I'm talking about. Sure you can look it up, but what a freakin' pain.

One of my favourite features of Java is the Exception object. Exceptions are basically object based errors which methods are defined to throw. Utilizing exceptions are often misunderstood. Frequently programmers will simply throw the offending Exception up to the calling method. This isn't great from a data coupling point of view but the worst of these offending implementations is the null return.

The null return is prevalent even in the JDK. It is the absence of a return value from a method because something didn't go right. java.util.Hashtable's get method is an example of the null error. The get method JavaDocs specifies that the return value is "null if the key is not mapped to any value in this hashtable". In other words, if something goes wrong, we're not going to throw an exception but just return null.

Null is like the faceless exception. Something clearly didn't go right because we got null back, but unless we go and look up what this means we're not sure what happened. Changing the method to provide a compile time context makes it much easier to understand what happened and handle it based on context.

// Using null as a return errorObject item = hashtable.get(key);if(item == null){    	// handle error}
// Using an Exception as a return errortry{    	Object item = hashtable.get(key);}catch(ObjectNotFoundException ex){    	// handle exception}

The amount of code makes very little difference but now we have context for the situation. Hashtable is fairly common so I'm sure you're used to seeing null come back, but if you're using an unfamiliar method and don't remember to check for null you're compile will proceed cleanly and eventually your program will spit up the dreaded NullPointerException.