Значения проверки наследования Java для нескольких переменных

Если у меня есть ситуация иерархии, как это:

class foo1{
    Foo2 foo2;
}

class foo2 {
    List<Foo3> foo3;
}

class foo3 {
}

class foo4 extends foo3 {
    Foo5 foo;
}

class foo5 {
    double value;
}

Я хочу получить этот финал double value но чтобы попасть туда, я должен пойти вниз по иерархии и проверить все нули. Я мог бы сделать что-то вроде этого:

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
                }
            }
        }
    }
}

Но это выглядит очень некрасиво, и, вероятно, есть гораздо более простой и чистый способ достижения той же цели. Я сталкивался с использованием рефлексии, но я не совсем уверен, как бы я использовал это вышеописанным способом. Есть идеи, как это сделать, не бросая NPE?

2 ответа

Решение

Там действительно нет. Возможно, это дефект Java (по крайней мере, через Java 7, см. Scala или дополнительные типы), но это также не совсем то, как люди на самом деле пишут Java.

Другими словами, просто бросьте NPE. В реальной ситуации большинство из них не должны быть нулевыми. Например, если Person класс имеет firstName поле, оно действительно должно всегда иметь firstName подарок. Там нет необходимости проверять, если firstName настоящее. Если нет, то это ошибка. Если это ошибка, выведите ошибку.

Потому что: что еще ты собираешься делать? Ваш пример кода очень нереалистичен, потому что код одинаково радует, независимо от того, обновляется внутреннее значение или нет. Там нет обработки ошибок - возможно, это ошибка глотания.

Ваш код не знает, что делать, поэтому выдает ошибку. Ошибка NPE.

Если ваш код знает, что делать в каждой ветви, то вам нужно написать 5 веток. Это настоящая цикломатическая сложность. Вы не можете отказаться от цикломатической сложности - вам нужно написать 5 блоков логики, чтобы справиться с этим. Но опять же, это не обычный случай для доступа вниз так далеко.

Начиная с Java 8 вы можете использовать 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.
    });

каждый map поворачивает Optional в новый, но только если исходные и целевые значения не равны NULL. Нулевое значение в любой точке приводит к пустому Optional который безопасно игнорируется.

Другие вопросы по тегам