Null Check Increasing cognitive complexity in code

Viewed 808

Consider the POJO as below:

class Person {

    private String name;
    private Address address;
    private UserProperties properties;

    //getters, stetters, etc
}

class Adddress {
    private String state;
    private Street street;
    private String country;
}

class Street { 
    private String line1;
    private String line2;
}

class PersonAttributes {
    private String nationality;
    private String age;
}

So the scenario is this:

  1. I do not have control over the POJO, it is a predefined structure.
  2. Any of the fields can be null.
  3. It is just a sample, the actual POJO is much more complex and nested.

When I query the field I have to add a null check to prevent null pointer exception.

For example:

if (person.getAddress() != null) {
     //do an operation on address

     if (person.getAddress().getStreet() != null) {
         //do operation on street
     }
}

Similarly for attributes and other nested fields.

Is there any alternative to the above approach that will reduce the complexity and avoid all these null checks?

I am fetching all the fields form a REST API and using Jackson to assign it to a POJO.

Is this approach correct for a highly nested JSON structure or there are other options which I should be using?

1 Answers

As already said in the comments, you cannot avoid the null checks.

You can 'beautify' them a bit:

import static java.util.Objects.*;

…

if( nonNull( person.getAddress ) )
{
    if( nonNull( person.getAdddress().getStreet() ) )
    {
        …
    }
}

You can introduce getters for the fields in the deeper nested elements on the top level elements:

class Person
{
    …

    public String getStreet()
    {
          var address = getAddress();
          var retValue = isNull( address ) ? null : address.getStreet();
          return retValue;
    }
}

…

if( nonNull( person.getStreet() ) )
{
    …
}

This can reduce the clutter of the top level code a bit.

If you are allowed to change the return types for your getters, using java.util.Optional could be an option, too:

class Person
{
    …

    public Optional<Address> getAddress()
    {
          return Optional.ofNullable( address );
    }

    public Optional<String> getStreet()
    {
          var retValue = getAddress().map( a -> getStreet() );
          return retValue;
    }
}

…

if( person.getStreet().isPresent() )
{
    …
}

But as said, the logic remains basically the same, it just looks differently.

Related