Search code examples
javainheritancenullpointerexceptionnullmember-variables

Java inheritance checking values for multiple variables


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?


Solution

  • 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.