2

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.

AlbCoder
  • 33
  • 4
  • 1
    Make getEmployee return an optional. – Thorbjørn Ravn Andersen May 30 '21 at 11:03
  • @ThorbjørnRavnAndersen hm, and if the Object Definitions are handled by another department and I am not allowed to change them? – AlbCoder May 30 '21 at 11:04
  • 3
    Don’t do one liners then. Check every time. That requires you to capture the value in a variable. Do this properly. The more careful you are now, the more robust your software will be. – Thorbjørn Ravn Andersen May 30 '21 at 11:06
  • As you noticed, your approach of Optional doesn't work. If you want to use Optional, you should use something like: `Optional.ofNullable(Store.getEmployee()).map(Employee::getBankAccount).map(BankAccount::getIban).orElse("")`. – Mark Rotteveel May 30 '21 at 11:11
  • Hi & Welcome! :-) Does this (NOT) answer your question: https://stackoverflow.com/q/10391406/592355 ?? ..xD – xerx593 May 30 '21 at 11:21
  • @MarkRotteveel thats an good idea. Would be better if you post this as an answer, so I can upvote it. – AlbCoder May 30 '21 at 13:11

1 Answers1

3

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("")
Mark Rotteveel
  • 100,966
  • 191
  • 140
  • 197