2

If I have a hierarchy situation like this:

class foo1{
    Foo2 foo2;
}

class foo2 {
    List<Foo3> foo3;
}

class foo3 {
}

class foo4 extends foo3 {
    Foo5 foo;
}

class foo5 {
    double value;
}

I want to get that final double value but to get there I have to go down the hierarchy and check for all the nulls. I could do something like this:

if(foo1 != null) {
    if(foo.foo2 != null) {
        if(foo.foo2.foo3 != null) {
            if( ((foo4) foo.foo2.foo3).getFoo5() != null) {
                if(((foo4) foo.foo2.foo3).getFoo5().getValue() != null) {
                    //do something
                }
            }
        }
    }
}

But that looks very ugly and there's probably some much easier and cleaner way to achieve the same goal. I've come across using reflection but I'm not really sure how I would go about using that in the above way. Any ideas how to do that without throwing an NPE?

Richard
  • 5,840
  • 36
  • 123
  • 208
  • 1
    I'd advise that you create objects that are 100% ready to go so you don't have to check for nulls. – duffymo Nov 03 '15 at 01:34
  • As shown in the link above, instead of having a thousand nested if statements, you can use &&. – Tot Zam Nov 03 '15 at 01:37
  • One of the whole points in using Object-Orientation vs. pre-OO "structures" is that you can guarantee that an Object is in a valid state at all times by controlling access to its members via constructors, and methods/setters that enforce rules. That is, you can make sure that your nested objects contained (at various levels) in `foo1` are ***never*** null. But, with no access control in place like in your example (the vars are just available) there is no avoiding doing null checks. – Stephen P Nov 03 '15 at 01:43

2 Answers2

2

There really isn't. Arguably this is a defect of Java (at least through Java 7, see Scala, or Optional types), but it's also just not how people actually write Java.

In other words, just throw an NPE. In a real-life situation most of those shouldn't be null. For example, if a Person class has a firstName field, it really should always have a firstName present. There's no need to check if firstName is present. If not, it's an error. If it's an error, throw an error.

Because: what else are you going to do? Your sample code is very unrealistic because the code is equally happy proceeding whether the innermost value is updating or not. There's no error handling - arguably, it's error swallowing.

Your code doesn't know what to do so it throws an error. The error is an NPE.

If your code does know what to do, at each branch, then you need to write 5 branches. That's real cyclomatic complexity. You can't wish away cyclomatic complexity - you actually have to write 5 blocks of logic to handle it. But again, that's not the usual case for accessing down that far.

djechlin
  • 59,258
  • 35
  • 162
  • 290
2

As of Java 8 you can leverage Optional.

Optional.ofNullable(foo1)
    .map(f1 -> f1.foo2)
    .map(f2 -> f2.foo3)
    .map(f3 -> (foo4) f3)
    .map(f4 -> f4.getFoo5())
    .ifPresent(f5 -> {
        // Do something with f5.
    });

Each map turns the Optional into a new one, but only if the source and target values are both non-null. A null value at any point ends up yielding an empty Optional which is safely ignored.

John Kugelman
  • 349,597
  • 67
  • 533
  • 578