Check chains of "get" calls for null

Viewed 37735

Let's say I'd like to perform the following command:

house.getFloor(0).getWall(WEST).getDoor().getDoorknob();

To avoid a NullPointerException, I'd have to do the following if:

if (house != null && house.getFloor(0) && house.getFloor(0).getWall(WEST) != null
  && house.getFloor(0).getWall(WEST).getDoor() != null) ...

Is there a way or an already existing Utils class that does this more elegantly, let's say something like the following?

checkForNull(house.getFloor(0).getWall(WEST).getDoor().getDoorknob());
10 Answers

Very old question, but still adding my suggestion:

I would suggest instead of getting the DoorKnob from the House you should try to let the DoorKnob be provided to this class from the calling code, or by creating a central lookup facility specifically for this purpose (e.g. a DoorKnob service)

implementing nullPointer try/catch with a Supplier you can send it all chain of get

public static <T> T getValue(Supplier<T> getFunction, T defaultValue) {
    try {
        return getFunction.get();
    } catch (NullPointerException ex) {
        return defaultValue;
    }
}

and then call it in this way.

ObjectHelper.getValue(() -> object1.getObject2().getObject3().getObject4()));
// Example
LazyObject.from(curr).apply(A.class, A::getB).apply(B.class, B::getC).apply(C.class, C::getD).to(String.class);

// LazyObject.java
public class LazyObject {

private Object value;

private LazyObject(Object object) {
    this.value = object;
}

public <F, T> LazyObject apply(Class<F> type, Function<F, T> func) {
    Object v = value;
    if (type.isInstance(v)) {
        value = func.apply(type.cast(v));
    } else {
        value = null; // dead here
    }
    return this;
}

public <T> void accept(Class<T> type, Consumer<T> consumer) {
    Object v = value;
    if (type.isInstance(v)) {
        consumer.accept(type.cast(v));
    }
}

public <T> T to(Class<T> type) {
    Object v = value;
    if (type.isInstance(v)) {
        return type.cast(v);
    }
    return null;
}

public static LazyObject from(Object object) {
    return new LazyObject(object);
}

}
Related