В случае, если вы не можете избегать нарушения Закона Деметры (LoD), как указано в выбранном ответе, а при Java 8 вводите Необязательно , это было бы, вероятно, лучшей практикой для обработки нулей в цепочках получения, таких как ваша.
Тип Optional
позволит вам передавать несколько операций с картой (которые содержат вызовы get) подряд. Нулевые чеки автоматически обрабатываются под капотом.
Например, когда объекты не инициализированы, print () не будет выполняться, и исключения не будут выброшены. Все это мы бережно берем под капот. Когда объекты будут инициализированы, будет сделана печать.
System.out.println("----- Not Initialized! -----");
Optional.ofNullable(new Outer())
.map(out -> out.getNested())
.map(nest -> nest.getInner())
.map(in -> in.getFoo())
.ifPresent(foo -> System.out.println("foo: " + foo)); //no print
System.out.println("----- Let's Initialize! -----");
Optional.ofNullable(new OuterInit())
.map(out -> out.getNestedInit())
.map(nest -> nest.getInnerInit())
.map(in -> in.getFoo())
.ifPresent(foo -> System.out.println("foo: " + foo)); //will print!
class Outer {
Nested nested;
Nested getNested() {
return nested;
}
}
class Nested {
Inner inner;
Inner getInner() {
return inner;
}
}
class Inner {
String foo = "yeah!";
String getFoo() {
return foo;
}
}
class OuterInit {
NestedInit nested = new NestedInit();
NestedInit getNestedInit() {
return nested;
}
}
class NestedInit {
InnerInit inner = new InnerInit();
InnerInit getInnerInit() {
return inner;
}
}
class InnerInit {
String foo = "yeah!";
String getFoo() {
return foo;
}
}
Итак, с цепочкой ваших геттеров это будет выглядеть так:
Optional.ofNullable(house)
.map(house -> house.getFloor(0))
.map(floorZero -> floorZero.getWall(WEST))
.map(wallWest -> wallWest.getDoor())
.map(door -> wallWest.getDoor())
Возвращение этого будет что-то вроде Optional<Door>
, что позволит вам гораздо безопаснее работать, не беспокоясь о нулевых исключениях.