Best Practices: Avoid Returning Null

June 9, 2010 by · 5 Comments 

I recall the first oddity that struck me about Java programming is that it seems common practice to test returned objects for null. I find it frustrating and inefficient to scatter if conditions throughout my code just to see if I have a valid object instance returned. 

Receiving null is confusing. When you make a function call and the result is null what does it mean? Was the data not found? Was there an exception in the function that was silently swallowed resulting in the return of a null object? You’re not really sure if null is an expected return value. If no exception is thrown then you just kind of assume that null is a valid return value. However, you can’t really do anything with the returned null object so what do you do now?

Here are a couple of alternatives to returning null:

Use the Empty Collection Methods

If you are working with returning collection objects from your function you should return an empty collection rather than a null object. This is very easy to do with the Collections class. There are three static methods available:

  • Collections.emptyList()
  • Collections.emptySet()
  • Collections.emptyMap()

An empty List is easily instantiated for return as shown here:

   List<String> myList = Collections.emptyList();

Returning an empty List eliminates the required check for null by the function caller. Now instead of having code which looks like this:

   List<String> names = getNames();
   if(names != null) {
      for(String name : names) {
         System.out.println(name);
      }
   }

You can simply write the following without worrying about a NullPointerException:

   List<String> names = getNames();
   for(String name : names) {
      System.out.println(name);
   }

This second example is much cleaner, easier to read and understand. Returning empty Collections is much safer as well since it avoids the potential run time exception: NullPointerException.

An unchecked exception represent defects in the program (bugs) - often invalid arguments passed to a non-private method. To quote from The Java Programming Language, by Gosling, Arnold, and Holmes : “Unchecked runtime exceptions represent conditions that, generally speaking, reflect errors in your program’s logic and cannot be reasonably recovered from at run time.” [1]

Certainly an empty collection is not a bug! So lets just return an empty collection rather than a null reference. In addition, testing for an empty collection is a lot more intuitive than testing for null.

   List<String> names = getNames();
   if(names.isEmpty()) {
      //throw an Exception
      //or do something else
      //or do nothing at all

   }

Throw an Exception

It’s perfectly acceptable to throw a custom checked exception alerting the calling client that the requested object cannot be populated or retrieved. This approach is much more revealing and forces the calling client to handle the potential problem. It also eliminates the need to check the returned object for null.

A checked exception is guaranteed to be handled so you gain more control over your program. A RuntimeException may or may not be handled by the caller and will bubble up until either it is caught or reaches the top of the caller chain.

Conclusion

Nulls are useful under certain conditions when null values are expected. However, for the above conditions with collections and data retrieval I feel it has been abused. Use the empty collection and avoid returning null objects whenever possible. It will make code cleaner, easier to read and debug.


Citations:

1. “checked versus uncheck exceptions” JavaPractices.com. 2010 Hirondelle Systems. 6 June 2010 <http://www.javapractices.com/topic/TopicAction.do?Id=129>


No related posts.

About Frank Salinas
Frank is a senior level Java developer working for a privately owned company based in San Francisco, California. He has over 12 years of experience developing software on Microsoft and Linux/Java/JEE platforms and specializes in SaaS, eDiscovery and Document Review platforms.

Comments

5 Responses to “Best Practices: Avoid Returning Null”
  1. Veera says:

    That ts very useful idea. I always initialize my return variable to null and then if my function does not produce a valid output, i send that null to my caller function. But as you said, if we can return an empty list, we could avoid a possible null pointer exception scenario.

    but, this idea holds good only for the methods which return a collection kind of object, isn’t it?

    • Yes, the empty collection methods are only useful for functions that return collection objects. For other types of objects the developer needs to decide how to handle potential situations where the requested object can not be retrieved or populated. Typically null is returned but I am suggesting to consider throwing a checked exception in these cases to force the calling client to handle the situation.

      Consider retrieving a user account object but the id passed into the function is not found in the database. the UserAccount object is initialized to null and because a record is not found is returned from the function as null. Now the calling client does not check for null and attempts to access a null property of the UserAccount object. A NullPointerException is thrown and begins bubbling up until an exception handler for NullPointerException is found.

      In my opinion I’d rather know about and handle a checked exception such as UserAccountNotFoundException than a NullPointerException which is very generic and may be difficult to track down.

  2. I think your suggestion about empty collections is fine, but the one about checked exceptions is not :-)

    While that makes impossible for the caller not to handle the potential “no result” event, it often forces sometimes a try -> dosomething -> catch CheckedException -> throw UncheckedException – code style whenever the caller can’t actually proceed without the data it requires.

    An unchecked exception would serve better – there the client could decide whether to handle it – if it’s able to – or just let it propagate if it can’t.

    Other useful patterns are the Null Object http://cs.oberlin.edu/~jwalker/nullObjPattern/

    or the maybe pattern:
    http://blog.tmorris.net/maybe-in-java/

    Alan (franzeur@twitter)
    http://twitter.com/franzeur

    • Alan,

      I wasn’t trying to make a blanket statement that an exception should always be thrown. It really depends on the situation at hand and what the expected output of the function should be. Null may very well be the appropriate return value but it should be well documented.

      In other cases it might make more sense to throw an exception particularly in cases where if the returned value is null an exception is thrown anyway. I guess my point is if null is an unexpected return value then throw an exception. I prefer a checked exception to keep the handling of the error close, and within the function caller. Also, as I cited above:

      “Unchecked runtime exceptions represent conditions that, generally speaking, reflect errors in your program’s logic and cannot be reasonably recovered from at run time.”[1]

      The reason behind this post is to see less of this:

      if( myObject != null) {
      //do the work
      }

      Thanks for commenting and providing the links. The Null Object pattern is interesting.

  3. Robert Packwood says:

    Interesting article,

    I agree that returning a null as default behaviour is a dangerous practice due to the aforementioned NullPointerException.

    We also want to minimise the amount of unnecessary code that we have in our code base i.e. if (null) statements and try-catch blocks, which obscure the real business logic that we are trying to implement.

    I like Allan’s suggestion that a RuntimeException should be used as this definitely results in the cleanest code leaving it up to the implementer to decide how they want to cater for the exception.

    I’ve never been completely comfortable with this approach due to the definition that you mention of RuntimeException.

    “Unchecked runtime exceptions represent conditions that, generally speaking, reflect errors in your program’s logic and cannot be reasonably recovered from at run time.”

    This statement implies that you should only throw a RuntimeException if something goes wrong within the method that is being called due to a programming error. However I think what this means is that a RuntimeException should be thrown whether the programming error lies in your method or the calling code.

    I believe that the calling code should always know before hand whether the data is available that it is requesting, as such if it asks for data that doesn’t exist then it’s a programming error and warrants a RuntimeException as it was detected in your method.

    I believe the IllegalArgumentException is an example of this. This is thrown by a method when the calling code provides some erroneous data, it is in no way a coding error in the method itself. Needless to say it is a RuntimeException.

    Sorry for the wordy reply, was thinking it through as I was typing.

    Rob Packwood

    P.s. If Veera is still following this I would say a variable should never be initialised to null. It opens you up to all sorts of NullPointerException problems, if you don’t initialise then your IDE will advise you that have a potentially uninitialised variable that you can deal with appropriately (i.e. not setting to null). The only time I believe you need to initialise to nulis when you need to close a connection/stream in a finally block.

Speak Your Mind

Tell us what you're thinking...
and oh, if you want a pic to show with your comment, go get a gravatar!