Допустим, я хотел бы выполнить следующую команду:
house.getFloor(0).getWall(WEST).getDoor().getDoorknob();
Чтобы избежать исключения NullPointerException, мне нужно будет сделать следующее, если:
if (house != null && house.getFloor(0) && house.getFloor(0).getWall(WEST) != null
&& house.getFloor(0).getWall(WEST).getDoor() != null) ...
Существует ли способ или уже существующий класс Utils, который делает это более элегантно, скажем, что-то вроде следующего?
checkForNull(house.getFloor(0).getWall(WEST).getDoor().getDoorknob());
Лучшим способом было бы избежать цепочки. Если вы не знакомы с Законом Деметры (LoD), на мой взгляд, вам следует это сделать. Вы привели прекрасный пример цепочки сообщений, которая слишком тесно связана с классами, о которых ей нечего знать.
Закон Деметры: http://en.wikipedia.org/wiki/Law_of_Demeter
Вы, конечно, можете просто заключить все выражение в блок try-catch, но это плохая идея. Что-то более чистое - это образец объекта Null . При этом, если в вашем доме нет этажа 0, он просто возвращает Floor, который действует как обычный этаж, но не имеет реального содержимого; Полы, когда их спрашивают о стенах, которых у них нет, возвращают аналогичные «нулевые» стены и т. Д. В дальнейшем.
Не существует метода checkForNull
, который вы могли бы написать, который упростил бы это (это просто не то, как вызов методов и оценка аргументов работают в Java).
Вы можете разбить связанные операторы на несколько операторов, проверяя на каждом этапе. Однако, возможно, лучшим решением будет в первую очередь, чтобы эти методы не возвращали null
. Существует нечто, называемое Шаблон пустого объекта , который вы, возможно, захотите использовать вместо него.
Убедитесь, что вещи, которые не могут быть логически нулевыми
, таковыми не являются. Например, в доме всегда есть западная стена. Чтобы избежать таких исключений в состоянии, у вас могут быть методы для проверки наличия ожидаемого состояния:
if (wall.hasDoor()) {
wall.getDoor().etc();
}
По сути, это проверка на нуль, но она может быть не всегда.
Дело в том, что вы должны что-то сделать, если у вас есть null
. Например - вернуть
или выбросить IllegalStateException
А чего делать не следует - не ловить NullPointerException
. Исключения времени выполнения не предназначены для перехвата - не ожидается, что вы сможете восстановить их, и полагаться на исключения для логического потока не рекомендуется. Представьте, что вы на самом деле не ожидаете, что что-то будет null
, и вы поймаете (и запишите) исключение NullPointerException
. Это не будет очень полезной информацией, так как многие вещи могут быть нулевыми
в этот момент.