Search code examples
javanullpointerexceptionoption-typegetter-setter

How to avoid NullPointerExceptions when calling getter-methods on a nested class


Hope you can help me with my question. Actually I know there are solutions (e.G. nullchecking), but I am searching for a super-elegant solution! In the best case a oneliner. Hopefully, you can help me.

I will describe now the problem by using simple examples.

Description of the situation

I have a Java object, that contains other Java objects (nested Java object) next to other simple member variables.

Class Store:

  • String Name
  • String City
  • Employee Employee

Class Employee:

  • String Name
  • Integer Age
  • BankAccount BankAccount

... and so on.

You can see that the Store object -> contains: Employee object -> contains: a BankAccount object.

Problem

To call the age of the Employee from the Store object, I would have do do:

Store.getEmployee().getAge();

Or if I want the Bankaccount IBAN, I would have to do

Store.getEmployee().getBankAccount().getIban();

However, if a Store has no Employee, .getEmployee() will cause a NullPointerException. The same counts for the Bankaccount.

Of course I can do

if(Store.getEmployee() != null) {
    if(Store.getEmployee().getBankAccount() != null) {
        System.out.println(Store.getEmployee().getBankAccount().getIban();
    }
}

But this is like super annoying.

Is there a more simple solution?

Note: Optionals don't work either, because

Optional.ofNullable(Store.getEmployee().getBankAccount().getIban().orElse("");

does not work, when Store.getEmployee() is already causing an exception.

Edit Please note, that the Objects itself should not be part of the solution. Of course you can modify the objects so that the return an optional or do the null checking itself. The reason behind this is that you just take the objects and process them but you are not allowed to configure them.


Solution

  • You can use the following:

    Optional.ofNullable(store.getEmployee())
            .map(Employee::getBankAccount)
            .map(BankAccount::getIban)
            .orElse("")
    

    You should also consider to define the getEmployee method with return type Optional<Employee>, in which case you can change it to:

    store.getEmployee()
            .map(Employee::getBankAccount)
            .map(BankAccount::getIban)
            .orElse("")