Easy defensive programming in Java: our solution

Nulls are common source of problems in many object oriented languages including Java. The inventor of null pointer famously referred to his invention as “The Billion Dollar Mistake”. In this article we assume that you are already aware why he says so.

Today we are going to share and suggest our approach to tackling this issue. Let’s go step by step and see how we came up with the solution.

One of the ways to reduce potential problems caused by nulls is to be defensive against them. We’ll use following simple class as our example throughout this article:

So the simplest thing we can do is to check every argument of every method or constructor and throw exception if its value is null like this:

Such an approach has several drawbacks:

  1. it adds 3 code lines for each argument;
  2. these checks contain duplicated logic;
  3. it decreases percentage of code coverage.

Let’s look at the 3rd one in more details for a moment. We could probably have unit tests for Greeter implemented like this:

So let’s use jacoco to get a coverage report:

That doesn’t look very nice, we’d like to have 100% coverage for such a basic class. But we didn’t get it cause we apparently have not tested null cases.

Now, let’s return to our 3 drawbacks. One way we can mitigate them is to use Objects.requireNonNull  method which encapsulates null  check. So we can rewrite our class like this:

So here we:

  • have only 1 code line for every argument;
  • eliminated duplication;
  • and actually get our coverage to 100%! See:

But the point about coverage is kind of deceiving because we improved coverage, but didn’t get any more safety. So that’s just a disguise, not a real solution. After all we can still miss a check, write none of them at all, or mess it up like this:

So it would be nice to actually test the presence of null checks. But that means, that we have to manually write one test per every argument of every method. And probably no one would ever want to do such a thing.

And here comes NullDefenseVerifier  (https://github.com/besmart-mobile/nulldefense-verifier). What it can do for you is to automatically cover every argument of every constructor and method (both static and instance) with tests. All you need to do is to write only one test method for a class, like this:

One more cool thing we can do is to use lombok (https://projectlombok.org/) generated checks. What it does is generating a proper null check for every argument annotated with @NonNull  annotation. So our Greeter can look like this and still pass implements_null_defense  test:

With those two complementary tools all we need to do to have a null-free codebase is just to write one single-line test for a class and put a @NonNull  annotation on every reference type argument. That simple!

NullDefenseVerifier  is developed and maintained by our company. We use it our production code. It is completely free and open source, you are welcome to download it and know more about its usage on our github page.

P.S.: For some of you wondering what should we do in case some of our arguments are optional, there are two good ways:

  • write separate overloaded methods: one without this optional argument and one with this argument as required;
  • use Optional<T>  type as it clearly communicates its optional semantic.
Back to Top