Подтвердить что ты не робот

Должен ли я использовать Java8/Guava Необязательно для каждого метода, который может возвращать null?

Необязательный используется для представления объекта с нулевым значением. Некоторые виды использования этого класса включают

  • Как метод возвращаемого типа, в качестве альтернативы возврату нулевого значения в укажите, что значение не было доступно
  • Чтобы различать "неизвестные" (например, не присутствующие на карте) и "известно, что не имеет ценности" (присутствует на карте, со значением Optional.absent())
  • Чтобы обернуть нулевые ссылки для хранения в коллекции, которая не поддерживают нуль (хотя есть несколько других подходов к этому, что следует считать первым)

В первом случае нужно ли возвращать Необязательный во всех методах возвращаемого значения?

4b9b3361

Ответ 1

Итак, что не так с необязательным?

Вопрос, с которым мы сталкиваемся: будет ли JDK 8 Необязательные объекты избавляться от нулевых ссылок? И ответ - решительный нет! Таким образом, хулители сразу же задают вопрос о его значении: тогда что хорошо для того, что мы уже не могли сделать другими способами?

В отличие от функциональных языков, таких как SML или Haskell, которые никогда не имели понятия нулевых ссылок, в Java мы не можем просто избавиться от нулевых ссылок, которые исторически существовали. Это будет продолжать существовать, и они, возможно, имеют их правильное использование (просто упомянуть пример: трехзначная логика).

Я сомневаюсь, что намерение с классом "Необязательно" заключается в замене каждой единственной ссылочной ссылки, но на помощь в создании более надежных API-интерфейсов, в которых, просто прочитав подпись метода, мы могли бы сказать, можем ли мы ожидать дополнительного значения или нет, и заставить программиста использовать это значение соответствующим образом. Но в конечном счете, Необязательный будет просто еще одной ссылкой и с учетом тех же недостатков любой другой ссылки на языке (например, вы можете вернуть null Необязательный). Совершенно очевидно, что опция не будет экономить день.

Как эти необязательные объекты предполагается использовать или они ценны или нет в Java, это вопрос жаркие споры в список рассылки лямбда проекта. От хулителей мы слышим интересные аргументы вроде:

Таким образом, очевидно, что преимущества Необязательного являются действительно сомнительными и, вероятно, ограничены для улучшения удобочитаемости и обеспечения соблюдения контрактов с открытым интерфейсом.

Я действительно считаю, что принятие этой необязательной функциональной идиомы, скорее всего, сделает наш код более безопасным, менее оперативным для устранения проблем с разыменованием и, как следствие, более надежным и менее подверженным ошибкам. Конечно, это не идеальное решение, потому что, в конце концов, необязательные ссылки также могут быть ошибочно установлены на нулевые ссылки, но я ожидаю, что программисты придерживаются соглашения о том, что не передают нулевые ссылки, где ожидается дополнительный объект, мы сегодня считаем хорошей практикой не передавать нулевую ссылку, где ожидается сбор или массив, в этих случаях правильным является передача пустого массива или коллекции. Дело здесь в том, что теперь у нас есть механизм в API, который мы можем использовать для того, чтобы сделать явным, что для данной ссылки у нас может не быть значения для ее назначения, и пользователь вынужден API-интерфейсом проверить это.

Цитата статья Google Guava об использовании необязательных объектов:

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

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

Некоторые влиятельные разработчики, такие как Стивен Колеборн и Брайан Гетц, недавно опубликовали несколько интересных статей о правильном использовании необязательного. Я особенно нашел полезным следующее:

Ответ 2

Как замечание, я считаю, что один из самых важных аспектов, который необходимо учитывать при разработке приложения, заключается в том, чтобы решить, как обращаться с "нулевой проблемой". В этом отношении первым шагом будет определение возможных "источников" нулей. Например, база данных или внешние библиотеки, используемые в проекте. Следующим шагом было бы "скрыть" проблему, а именно: обернуть проблематичный код (с использованием опции "Дополнительно" ) и тем самым заблокировать распространение нуля в системе, где ничего не подозревающий код может вызвать NPE.
Чтобы ответить на ваш вопрос, это зависит... В большинстве случаев я бы сказал, что это ненужно, поскольку он создает большую работу без ценности (например, я бы не использовал необязательный для методов, которые вызывают другие частные методы внутри классов, или методы, вызывающие методы класса private-private), но код, который существует в тонкой границе различных "проблем" (или слоев) в вашем приложении (подпись интерфейсов/классов, которые вы используете для запроса хранилища данных, например, или pojos, используемые для переноса данных, которые могут иметь нулевые свойства - DTO или более общее описание опубликованных API различных модулей) должны избегать "утечки" "nulls в некоторые другие области с различными проблемами.

Ответ 3

По сравнению с Guava одна неприятная проблема с java.util.Optional заключается в том, что она не предоставляет такой метод, как

orElse(Optional<T>): Optional<T>

который, с другой стороны, определен в com.google.common.base.Optional как

or(Optional<T>): Optional<T>

Отсутствие этой специфической функции ограничивает монадические приложения Java 8 Необязательно.

UPDATE:

Guava or(Optional<T>) может быть реплицирован как в Java 8 Необязательно как

optionalA.map(Optional::of).orElse(optionalB)

или

optionalA.map(Optional::of).orElseGet(() -> computeOptionalB)

UPDATE:

В Java 9 (наконец!) вы сможете использовать Optional.or(Supplier<Optional<T>>):

optionalA.or(() -> computeOptionalB)

Это аккуратно!