«    »

How to Handle Null Values in Code

One fairly common coding style I have seen from more experienced developers is what I will call highly-aggressive null checking. Such developers have most likely been burned by null pointer exceptions in the past and hence have evolved a style of coding which confirms that parameters or fields are non-null before using them. The code below shows a typical example of this coding style.

public void placeOrder(Customer customer, Order order) {
  if (customer != null && order != null) {
    // ...
  }
}

I am not a big fan of this style of coding, although I do appreciate that it results in more robust code than code that ignores null checking completely. My coding style instead uses precondition checks to assert that parameters or fields are not null before using them. Rewriting the above example in my style results in the following code.

public void placeOrder(Customer customer, Order order) {
  assert customer != null;
  assert order != null;
  // ...
}

These two styles different in their approach to error handling: mine uses the fail fast principle, while the first uses the degrade gracefully principle. See my article on Fail Fast or Degrade Gracefully for details on the differences between the two. Long-time readers may find my preferred style surprising given my stated preference for the degrade gracefully approach. Let me clarify my position. I still do prefer the degrade gracefully approach, especially for the higher level application architecture & design. My use of fail fast at the detailed coding level is based primarily on my philosophical view of coding, which is to use the technical computer language (Java in the above example) to construct a language representing the business problem domain. The placeOrder method becomes part of the syntax of this business language that semantically only makes sense to apply to an actual customer & order. Having the method handle null arguments does not make sense when expressed in terms of the business language. From a more pragmatic viewpoint, having either the customer or order be null almost certainly reflects an error in the calling code. Blindly ignoring null values throughout the code base significantly increases the risk of errors going undetected.

One special case of aggressive null checking that really bothers me is checking for null collections. Below is an example:

public class Customer
  private List orders;
  public List getOrders() {
    return orders;
  }
}
public class CustomerProcessor {
  public void checkOrders(Customer customer) {
    if (customer.getOrders() != null) {
      for (Order order : customer.getOrders()) {
        // ...
      }
    }
  }
}  

In terms of the business domain, a customer can have zero or more orders. So the collection can be empty. But the relationship exists for every customer – a null collection has no business meaning. Checking if a collection is null therefore adds meaningless noise to a method. My approach instead is to have a class invariant that the collection is always defined, which then avoids the need for null checking. This is easily accomplished by initializing the collection at the time of definition. Rewriting the above code in my style results in the following:

public class Customer
  private List orders = new ArrayList();
  public List getOrders() {
    return orders;
  }
}
public class CustomerProcessor {
  public void checkOrders(Customer customer) {
    for (Order order : customer.getOrders()) {
      // ...
    }
  }
}  

I believe that this style of coding is more readable and understandable, in large part because it more closely matches the problem domain being modeled without the baggage of extra null checks. This approach does require more thought regarding whether fields and parameters can or should be null, which is perhaps one reason why aggressive null checking is often used instead.

My approach can be compared to defining the nullity of columns in a database schema. One advantage with database design is column nullity is an explicit part of the database schema language, whereas programming languages such as Java provide no explicit support for the concept. I have long though that an explicit syntax for nullable versus non-nullable variables would be an interesting experiment. I have seen experimental languages with such a feature but I have not heard of any remotely mainstream language that does so. One possible syntax is to suffix nullable variables with a question mark. The compiler could then verify at compile time that such variables are checked if they are null before being used. Additionally at run time an exception could be thrown if a non-nullable variable is assigned a null value. Below is an example of what such a revision to Java would look like:

public void placeOrder(Customer customer, Order order, Discount? discount) {
  // Customer and Order are not nullable, Discount is nullable
  // Invoking a method on discount here would be flagged as an error by the compiler: 
  double percentageDiscount = 1.00; 
  if (discount != null) {
    // No error because we have checked if discount is null 
    percentageDiscount = discount.calculatePercentage();
  }
  // Can invoke methods on order and customer without checking if they are null.
  order.prepareToBePlaced(percentageDiscount);
  customer.addOrder(order);
}

I am not a language designer so I do not know all the ramifications of such a language change. Therefore I am not saying that this should be added to Java, merely that it is a possibility. If you do want compiler support for dealing with nulls, then one alternative is to use the Eclipse IDE and enable its Java compiler for performing a static compile time analysis to warn of the use of variables that may be null (see image below).
Eclipse Null Warnings

If you find this article helpful, please make a donation.

20 Comments on “How to Handle Null Values in Code”

  1. takacsot says:

    Hello

    I think you assert example is not what you really what. If you EXPEXT not gettin NULL as an input you must use such a programmign technics whihc is explicite. Asserts in Java isnot explicit. It could be switched off. Personally the only place where I use assert as a validator for input are non-public methods. Public methods are explicitelly checked.

    Bests
    Otto Takacs

  2. I mostly agree. But you make it sound like failing fast vs degrading gracefully is a matter of personal style. It is not! Each of these approaches has its own scope. Sometimes you just cannot degrade gracefully (or it doesn’t make sense) and your only choice is to terminate. On the other hand, I once worked on the project where terminating could mean loosing thousands of dollars. So, you need to think what is more appropriate in each situation.

  3. Mark Wilden says:

    You might want to check out C#.

    ///ark

  4. Otto, good point about being able to disable asserts. Personally, I think asserts should never be switched off and code under the assumption they won’t be. An alternative is to use an Assert class that uses a non-assert based check, which is what I did prior to Java 5.

    George, I didn’t mean to imply that failing fast vs degrade gracefully is a matter of personal style: the application’s requirements / design may dictate one over the other. In my experience many developers, even experienced ones, do not think about this and just code according to their personal style (i.e. aggressive null checking), without considering the ramifications.

    Mark, I did check out C# some years ago and don’t remember any relevant features. Has some language feature been added for dealing with nullity of variables?

  5. Rob says:

    The correct approach is to leave your asserts in (so the code fails fast in development) but also have the code degrade gracefully wherever possible in the “real” world – it’s very hard to explain to a customer that something “shouldn’t have happened” when they’ve lost a day’s work (or, in my case, when a panic() SPI call you left in a device driver took their entire system down).

    While ensuring your own objects are “fully” initialised – e.g. the orders member is initialised with an empty list – by the end of the constructor is quite definitely a good thing, relying on that being the case in a different class is not a safe approach. In Java your Customer class could easily be replaced by another implementation that exposes the same set of methods.

    In fact, if you design your CustomerProcessor code explicitly to use interfaces rather than classes in its formal parameter definition in order to reduce coupling and make it more re-usable in future, then you’re even less likely to be able to rely on a particular implementation guaranteeing a non-null List being returned by getOrders().

    Given you can almost always treat a null List and a List object which is empty as equivalent your checkOrders() should be explicitly checking for a null return from getOrders() and behaving the same way as for an empty list (do nothing, probably) – there’s no reason checkOrders() should be introducing constraints that it doesn’t really care about, i.e. by requiring checkOrders() to give a non-null result to avoid a NPE from the for loop. This is an example where “degrade gracefully” is clearly the better approach.

    As for checking whether the customer object is null, if you want this to fail fast then nothing fails faster than just throwing a NullPointerException! It would still be better (for the reasons I’ve given above) to have this degrade gracefully in the live environment, however. Again, a checkOrder() call that is passed a null customer should probably just return without doing anything.

    In summary, therefore, you should:

    a) enforce your business model in code wherever possible
    b) still assume a) hasn’t been done in any class that is defined externally to the one you are working on (even if you just wrote it yourself, five minutes ago)
    c) protect yourself against b) by putting asserts to cause “fail fast” in development
    d) implement “degrade gracefully” wherever possible to protect your users in the live environment.

    I’m afraid your checkOrders(), therefore, should look like:

    public void checkOrders(Customer customer) {
    assert customer != null : “customer is null”;

    if (customer != null) {
    List orders = customer.getOrders();

    assert orders != null : “orders is null”;

    if (orders != null) {
    for (Order order : customer.getOrders()) {
    // …
    }
    }
    }
    }

    not pretty, but at least it’s about as safe as it can be, and I guarantee you that your users care much more about that than how pretty your code is!

  6. Rob, thanks for the thorough comment. You make a compelling argument for checking nulls to degrade gracefully that almost convinces me.

    One consideration, however, is that there is no guarantee that degrade gracefully is indeed what is wanted in the live environment. Having a null customer or null set of orders likely represents a serious problem, and it is just as likely that the business sponsor does not want the transaction to go ahead with the system in an unknown and likely erroneous state.

    Plus, the code you have provided performs differently in development than the production environment (assuming you disable asserts in production). This introduces significant risk. If you want the code to gracefully handle the null customer or orders, I would log an error that the customer or order is null rather than use a development-only assert.

  7. [...] How to Handle Null Values in Code – Basil Vandegriend talks about a number of techniques for dealing with null values. [...]

  8. Kalpesh says:

    A pattern when returning a collection (getOrders) could be returning a valid object with 0 items in it.

    The caller wouldn’t need to check for null in such a case.

  9. Simon Wright says:

    In Ada 2005 you can specify that an access type (roughly, pointer) cannot be null;
    type T_P is not null access T;

    Similarly for a parameter:
    procedure Proc (P : not null access T);

    In both cases the compiler will check assignments, in the latter case at the point of call.

  10. The Nice programming language has fixed the nullpointer problem a long long time ago.

    http://nice.sourceforge.net/

  11. anonymous says:

    You should also consider to use the @NotNull annotation to mark parameters that shouldn’t be null.

  12. Casper Bang says:

    Clearly, null checking leaves you with the feeling that… it would be better if you could leave it out. But I think you are comparing apples and oranges. Asserts represents logical errors, faulty states in the application which are never permitted. Yet real life is often much more messy than we would like where you often potentially have to expect null as part of the normal control flow. Of course C# handles this a little better than Java, in that you have nullable types and static analysis tools will be able to deduce much more about your code than in Java. I seeem to remember Brian Goetz prototyping support for a @NotNull annotations for roughly the same purpose.

  13. Peter Maas says:

    Slightly on topic:

    In Groovy there is something called a safe dereference operator:

    customer?.getOrders().each{ it ->

    }

    The getOrders method on customer won’t be called if customer is null.

  14. Kit Davies says:

    When/if we get java closures, a nice option could be something like:

    asserting(customer != null) {
    List orders = customer.getOrders();
    asserting(orders != null) {
    for(order : orders) {

    }
    }
    }

    Then you get fail-fast and degrade-gracefully in a fairly
    readable format.

    BTW, Groovy has a ‘?’ notation for handling nulls. So:

    customer?.orders?.itemAt(1)

    would return null if either customer or orders were null.

    Kit

  15. Ivan Memruk says:

    You can use a method parameter annotation and wrap your classes into AOP proxies. The OVal validation framework does that. That way you will both express your constraints efficiently and not add any imperative noise into the code.

    You also don’t need to change Java this way.

  16. Thanks Peter and Kit for mentioning the Groovy ‘?’ notation. I wasn’t aware of it, and think it is a nice, concise syntax.

    I’m not sure I like having a @NotNull annotation in Java – it seems a little clunky (i.e. too verbose) compared to my syntax suggestion. It does have the advantage of not changing the syntax of the language, so I suppose it is more likely such an approach would eventually be adopted.

    Considering the bigger picture, the fact that languages, especially more recent ones, are adding special syntax for handling nulls or for supporting nullable types shows that this is an important issue.

  17. el gregorio says:

    Sun documentation at http://java.sun.com/j2se/1.4.2/docs/guide/lang/assert.html states,

    “Do not use assertions for argument checking in public methods.

    Argument checking is typically part of the published specifications (or contract) of a method, and these specifications must be obeyed whether assertions are enabled or disabled. Another problem with using assertions for argument checking is that erroneous arguments should result in an appropriate runtime exception (such as IllegalArgumentException, IndexOutOfBoundsException, or NullPointerException). An assertion failure will not throw an appropriate exception. “

  18. the_Tzar says:

    While writing an application that had to parse through a lot of binary data, I used assertions a lot. It allowed me to be very restrictive during development and to be very fault tolerant during deployment.
    Let’s face it, if I miss one character or if I get some metedata about textcolor wrong, I want to know during development, but I want to ignore it during deployment.
    So yes, assertions can be turned off and I expect them to be turned off.
    For nullpointers, what use is it to replace a NullpointerException by a IllegalArgumentException or an AsserionError. It all stopts your programm anyway and with good tooling you’ll know why allmost imidiately.

  19. Mark Wilden says:

    In C#, the ‘int’ type is not nullable, but the ‘int?’ type is.

    ///ark

  20. Ewald says:

    I am very glad I found your website on reddit. Thank you for the sensible critique. Me and my brother were just preparing to do some research about this. I am glad to see such reliable information being shared for free out there.
    Best Regards,
    Burton from Columbus city (remainder)

«    »