Like most Java developers I have a hatred for null values. They are incredibly annoying to deal with and Java gives you no good way to handle them. “Scripting” languages tend to be much more forgiving of null values which is one of the reasons they are popular. But, if you’re in Java, what are the best practices for dealing with null values?

I saw a presentation today that provided a quick overview of this problem and proposed an Optional generic type for bypassing null values. This is a cute trick but is still clumsy enough that I don’t see a particular advantage.

What I do in my own code, and what I request from developers I oversee, is that they try and obey one simple rule: don’t return nulls if you can reasonably avoid it.

The key here is “reasonably”. If you have to jump through hoops to create complex objects just to avoid returning a null, you’ve gone too far. But if your routine returns a collection, return an empty collection instead of a null. If it returns a string, return an empty string. You would be amazed at how much this improves your code reliability.

I also like to annotate my code with IntelliJ IDEA @Nullable and @NotNull annotations (they’re mentioned in the presentation). They allow the IDE to do static analysis and tell you immediately whether your code can generate a Null Pointer Exception (NPE) or not. But there are three big problems with this:

  • Only IDEA supports it. Most teams I work with are using Eclipse and these annotations don’t help them and complicate their lives.
  • The static analyzer can’t handle methods that are “too complex”. This means that you are occasionally forced to decompose methods that you didn’t originally intend to.
  • You need to be explicit. The analyzer understands that if you type “if (x != null)” that you don’t have to worry about x being null inside the if statement. But if you have a helper function “if (notNull(x))” then the analyzer won’t know that x is guaranteed to not be null.

Because of this, I tend to use the annotations on libraries and not on the application code.

Beyond that, there’s no silver bullet, it’s the tried and true:

“x = f(3); if (x != null) { then x is safe in here }”