Avoiding null checks in java

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

public void addAddressToCustomer(Customer customer, Address newAddress){
 if ( cutomer == 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 and are 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 this article that 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.

Related Posts

19 comments

Totally agree. Java 8 even has new constructs to help with null pointers, though I will avoid – a null in a business level class is an indication of an error condition, and shouldn’t be covered up by null checks.

Checking in for nulls in higher levels is handy. But actually it’s not the the clients responsibility to ensure a legal state of a component. Each component has to prove itself that it’s inputs meet the requirements (accepting / not accepting null is such).

In case you don’t have access to the javadoc of a component, how can you tell, that a parameter does accept null? In never version of Java you can use @NotNull and @Nullable to declare if a parameter either accepts null or not. But following this approach is just the tip of the iceberg, because you have to check other preconditions manually.

So are you suggesting that business logic should, in fact, check for null? I also don’t see a problem with doing that, as long as you do it cleanly (i.e. with Java 8 Optionals, or @NotNull and @Nullable annotations).

Thanks for your comments Igor. Yes this is exactly what I’m talking about 🙂

I expected more information.
Like using Objects.requireNotNull, Objects.equals, @NotNull, etc.
Assuming that the controller does everything right might be a bad idea, since it opens the door for a lot of (security) problems.

Thanks for your feedback. Objects.requireNotNull is just a syntactic sugar for null checking so we’re still forced to check for null arguments. The point of the article is NOT to check for null objects in the business logic layer and is based on my personal experience. 🙂 No silver bullet here.
About the controller thing, I’m not assuming that the controller does everything right but it does some basic validation of the client data before they’re passed to the business layer. Besides the cotnroller and the business service live in the same system. I can’t find any good reason why the controller can’t ensure that no null objects are passed. What kind of security issues do you have in mind?

Not checking for nulls in your business layer is fine and dandy provided the layers on either side abide by the rules, the security issues come in when one side pushes in a null and that can cause unexpected problems

IMO this isn’t so much a security issue, as it is an application bug. The application might crash, or have unexpected behavior, – which might be reflected in the UI. But the term ‘security issue’ might be an overstatement of this situation…

I have to disagree. Instantiating an object if it may not be needed is a waste of time and resources. Every time you create an object, there is a cost in memory, GC overhead, and CPU overhead. While I understand the argument about eliminating boilerplate, it is naive to say “just don’t do null checks”.

Thanks for your feedback Deven. Sorry but the point of the article is not :”just don’t do null checks” . The point of the article is “do null checks at the upper layers” or “protect your code by null object references”.

That is premature optimization! And premature optimization is the root of evil!

Most of the time it will be fine because these objects are mostly short lived which is actually a benefit rather than having to rely on long lived helpers, managers, etc.

Most application are not video encoders, I’d prefer to have clean, readable, easily maintainable and evolution code than nulls, on the long run it is usually less costly for the development. And if performance is a problem then we can address it with a code that can be understood.

[…] Avoiding Null Checks In Java – If you’re already on Java 8, NPEs may be a thing of the past. If not, this guide from Papapetrou Patroklos can help you avoid writing null checks before every dot operator, method invocation and return statement. IntelliJ’s contract annotations can often help alleviate this problem. […]

On another matter I find this code wrong anyway as it breaks the law of Demeter (in both forms)

customer.getAddress().getStreet()

The only way I know to not break the Law of Demeter is to follow the Tell, Don’t Ask principle. With this principle the code is way cleaner and there’s never a real need to null check from the client side.
So could have something like :

customer.compareAddress(AdressComparators.streetLike(“Timesquare”))

Of course the API can be reworked depending on the needs.

Experience showed me that if there’s this kind of null checks then the code is usually lacking internal business oriented API. Practicing Tell, Don’t Ask results in developing an internal and readable API. And that allow a much more clean, readable, evolutive code.

nice article. thanks.

I suggest a slightly different way: 1) the service layer (APIs and even lower backend) should try not to return any null values. 2) the service layer should always check null on the objects passed from the UI layers. Why? coz you don’t want your service layer down by an Null input from the UI level.

Thank you for the nice article and the link to Java8 Optional.

Hello ,

can you be please more descriptive about below line of statement?
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())

Thanks,
Vineet

Correct but still customer or getAddress() could be null 🙂

Leave a reply