One of the worst nightmares for Java developers (from junior to expert) is null object reference checking. I’m pretty sure you have seen code like this several times;

public void addAddressToCustomer(Customer customer, Address newAddress){
 if ( customer == null || newAddress == null)
 return;

 if ( customer.getAddresses() == null ){
   customer.setAddresses ( new ArrayList<>());
 }
 customer.addAddress(newAddress);
}

Personally I hate writing code for null check. In this post I will list some of the things that have worked well for me, based on my personal experience in production environments and systems.

  • Stop checking for null objects in all layers. Limit the checks only on the upper layers such as UI layer, presentation layer or the layer of your API controllers. In other words ensure that no null objects are passed from upper layers to the business logic layer.  For instance if you are developing a standard web application using Spring annotations then you’re probably have some classes annotated with @Repository , @Service , @Controller. Controllers are responsible for receiving client’s data and pass it to the @Service class for processing. It’s their responsibility to ensure that NO null objects are passed to the service layer. Service classes and below should not be null-safe. If they’re invoked with nulls then they should throw NPE to warn developers that they should fix this error. Remember that NPE is not a user error but a developer’s error and it should be always avoided.  Do the same with user inputs that comes from html forms or other user interface input.
  • If you follow the above approach you won’t be tempted anymore to write business logic based on the fact that an object is null or not. Null objects should not be used to decide the behavior of your system. They are exceptional values and should be treated like errors and not valid business logic state.
  • When returning a list from a method, always return an empty list instead of null. This will allow clients to iterate the list without checking for nulls. Iterating an empty list is totally accepted and will just do nothing, whereas iterating a null list will throw a NPE.
  • In your persistent layer when you search for a specific object (i.e. using its identifier) and it’s not found then a very common approach is to return a null object. Well, this will make all clients to manually check for this null case. In this case you have two alternatives. Either throw a run-time exception (i.e. ObjectNotFoundException ) or return an empty Object. I have used both of these options and my suggestion is to evaluate them depending on the overall architecture of your system and the tools / frameworks used.
  • When comparing a strings always put first the string that is less possible to be null so instead of

customer.getAddress().getStreet().equals("Times Square")

prefer

"Times Square".equals(customer.getAddress().getStreet())

  • If you’re using or planning to use Java8 then the new Optional class is here for you. Check out this article which clearly explains the use of Optional.

Next time you’re going to write some null check code try to think a little and decide if it’s redundant or not.

Avoiding Null Checks In Java

About The Author
- Patroklos Papapetrou is a Java architect, addicted to software quality and an agile team leader with more than 15 years of experience in software development. He believes and invests in people and team spirit seeking quality excellence. He’s one of the authors of SonarQube in action book, he is an active SonarQube community member and plugin contributor. He treats software systems as flowers that’s why he prefers calling himself a software gardener.

7 Comments

  • W. Biller
    Reply

    Using null checks only in the most upper layer is a bit vague ain’t it? Sure you checked that that variable isn’t null in that specific use case, but what about if one of your collegeaus reuses the one of the methods from the first use case and provided a null value?
    You don’t have to check for null in every layer, but at that layer where you use the variable. In most cases this is the most lower layer.

    You can use a Spring’s Assert or Guava’s Precoditions classes to minimize the amount of work.

    The provided source code is a good example for Design by Contract. You should provide Javadoc for the method whic clearly states that customer and newAddress must be not null. Or you can use @NonNull annotation.

    Another problem with the source is that it modified the internal representation of your the customer object. customer.setAddesses(new ArrayList()); You can perform this check in the addAddress method. But ideally your should initialize the list in a constructor. This would make the setAddresses unneccesary.

    http://en.wikipedia.org/wiki/Defensive_programming

    • tddmonkey
      Reply

      I disagree. Adding these checks will invariably be at multiple layers, at the very least the input layer and the layer at which it is used which to me is duplication.

      If another developer uses my code and provides a null then this is now /their/ problem and as long as my code is documented* that nulls are not allowed I see no need to provide checks for it. A well tested codebase has no need for defensive programming.

      * I personally prefer the use of Optional to mark parameters that could be null. The lack of Optional means it /must/ be present.

  • Marcel Kolsteren
    Reply

    The first code example that you show is indeed a pattern that I see many times in code written by fellow developers. Your point is that you don’t want to write these null checks, because they are often redundant. However, a much worse problem is that adding these kind of null checks mask bugs, so writing them should be avoided anyway! They prevent an NPE from happening, and result in something much worse than an NPE: the method just returns without doing anything, the system just continues executing, the end user will not be warned that something went wrong, and operations won’t see any error messages in the log. The “only problem” is that the system sometimes just skip things :-). The other way around, letting the NPE happen will result in a stack trace, so that it’s immediately known which chain of calls resulted in the NPE, and the actual problem can be fixed where it is: in the calling code, not in the called method!

    One of the things that worked well for you, was to prevent null lists from being created, by ensuring that an empty list is created instead. Your reasoning is that an empty list will do less harm, because it can just be iterated: nothing will happen, instead of an NPE. But again, doing nothing can be much worse than crashing!

    So, please, let’s fail fast! Let’s cherish NPEs! In the end, those stupid “if (x == null) return” statements will *silently* break down our systems. Stop writing them!

  • Reinier Zwitserloot
    Reply

    4 points:

    * An excellent practical tip for avoiding nulls is missing from this article: Use xOrDefault methods if they are available, and make sure your APIs have them. For example, starting with JDK8, you can use map.getOrDefault(key, valueIfKeyNotFound). For example, String v = map.getOrDefault(“foo”, “bar”); will mean ‘v’ is never null (assuming you didn’t put null values in the map itself, but that should go without saying). You can take a page out of java.util.Map’s playbook and use JDK8’s new ‘default’ mechanic to add these methods to your interface if (like j.u.Map!) you forgot to do that when you released the API!

    * Another simple tip: If a good ‘default’ value exists for some type, return that one to signal missing/empty if it is at all relevant to do that. For example, if your method returns a List, then you should generally just return an empty list and not null unless there’s an actual difference between ‘there is no meaningful value I can return for you’ and ‘there WAS a meaningful value, and it is the empty list’. For most APIs, there’s no functional difference between those 2 concepts. If that is the case, never return null, always return the empty collection. Same goes for the empty string, ‘midnight’ for something like a java.time.LocalTime, etcetera. Basically, if you ever catch yourself writing something like: if (x == null || x.isEmpty() { … }, then the API that gave you x should probably have been written such that it always returns the empty version and never null.

    * You may hate writing null checks, but the NPE is fantastic: It pinpoints exactly where you, as a developer, made a mistake. With an NPE stack trace in hand, I generally find the bug, and fix it, in about a minute. I’ll gladly fix 20 NPEs instead of having to fix only a single time where usage of Optional has resulted in some code mysteriously doing absolutely nothing, and not throwing an exception either. Fixing that one will usually take me, literally, far more than 20x the time taken to fix a single NPE problem. In this sense, Optional is not a good idea.

    * Optional is tricky in general. It wasn’t really meant for null handling in java, for a number of reasons. It exists in the API primarily to handle certain exceptional cases in JDK8 streams and lambdas APIs: For example, what is the sum of a list of integers, if the list is empty? That’s a different notion than null, and _this_ is what Optional was originally added to the JDK8 APIs for. Optional in java is a bad idea because all existing API doesn’t use it, and there’s no way it’s going to be retrofitted anytime in the next 10 years or more. For example, map.get() does not return an optional. Code that uses one way to handle a certain corner case (‘lack of value’ in this case) throughout is vastly easier to maintain versus an app that switches paradigms like a chameleon changes colours, and in java you will, pragmatically speaking, never be rid of nullchecks, so just stick with that paradigm. You can add annotations if you prefer for some compile-time assistance, that doesn’t clash with 15 years of established API. Scala has more experience with optional, and many scala experts agree that Optional should really only be in your return types (it should never show up as a method parameter), and it should be ‘unpacked’ ASAP. If that’s the goal, then you should use @NonNull and an annotation based code checking API. This gets you the same thing (compile-time / auto-complete-time notification that the return value may be null and should probably be checked for that), without clashing with all that existing API. It can also be retrofitted onto existing APIs without breaking compatibility, unlike Optional.

    * TL;DR: In java, Optional to avoid null checks is not going to work, please stop advising it.

    • Mario Fusco
      Reply

      I totally disagree! Optionals are the answer for all these problems. map.get() doesn’t return an Optional? Not a big deal, do Optional.ofNullable(map.get()) and you’re done.

      And by the way can you tell me the name of only one of those “Scala experts” advocating that Optional should be used only in return types?

    • Colin Vipurs
      Reply

      I totally agree with Mario on this one, Optional is fantastic (and can be used pre-Java 8 with Guava) because it reveals /intention/. For return values it’s a signal to the user of your code that this may or may not return a valid value. One of the OPs suggestions is to use an Exception when looking up an object from somewhere – except this isn’t an exceptional circumstance, it’s merely a data error and Optional as a return value is far more powerful than throwing an exception.

      In Scala, because Optional is so ingrained into the language, using it is a different beast. I would suspect the reason it’s said to only use it as a return value is that Scala supports named parameters and defaults which most of the time negates the use of Optional, both features which are missing in Java.

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>