Страницы

Поиск по вопросам

понедельник, 1 октября 2018 г.

Как лучше избежать NullPointerException при большой вложенности?

Под большой вложенностью имеется ввиду код вида:
param = foo.getSomthing1().getSomthig2().getSomthing3() ...
При этом в каждом вызове может вылететь NullPointerException. Хорошим примером является сгенерированные классы по XSD схеме. Мне нужно вытащить и присвоить некоторое значение, и если на пути встретится хоть одна отсутствующая нода (null в Java) - мне нужно присвоить null
Один из вариантов, это if вида:
if (foo != null && foo.getSomthing1() != null && ....) { param = foo.getSomthing1().getSomthig2().getSomthing3() ... }
При этом код становится нечитабельным. И простой конвертер объекта, сгенеренного по XSD схеме класса в плоскую Java структуру выглядит ужасно.
Есть вариант поместить в try catch :) Но это будет выглядеть ещё хуже, не говоря уже о производительности.
Слышал про операторы ?., ?:, ?[], но заставить из работать локально у меня не получилось, а так было бы интересным решением:
param = foo?.getSomthing1()?.getSomthig2()?.getSomthing3() ...
UPD: вариант с ?. был взят из неавторитетного источника. Имелся ввиду вероятно C#.
Подскажите, какие ещё могут быть способы?


Ответ

Есть такой вариант, но только для Java 8:
private Optional get(First first) { return Optional.ofNullable(first.getSecond()) .map(Second::getThird) .map(Third::getFourth) .map(Fourth::getString); }
Допустим у нас есть класс First, который в свою очередь содержит в себе поле с классом Second, который содержит Third, который содержит Fourth в котором нужное нам поле, пусть это будет String
Итого, чтобы получить string из Fourth, имея экземпляр класса First, нам нужна следующая конструкция String someString = first.getSecond().getThird().getFourth().getString()
Имея вышеописанный метод, мы делаем следующее: String someString = get(first).orElse(null);
Если один из вложенных классов окажется null, то мы просто получим someString = null, либо вместо null можно указать default значение.
Remark
Речь идет об использовании специального класса Optional введенного в Java 8. Для Java 7 можно воспользоваться Google Guava - там тоже есть аналогичный класс Optional

Комментариев нет:

Отправить комментарий