Статьи

Java 8 Необязательно: как его использовать

Java 8 поставляется с новым Optional типом, аналогичным тому, который доступен на других языках. В этом посте будет рассказано, как предполагается использовать этот новый тип, а именно, каков его основной вариант использования.

Что такое необязательный тип?

Необязательный — это новый тип контейнера, который переносит одно значение, если оно доступно. Таким образом, это означает, что значение может отсутствовать. Возьмем для примера этот метод:

1
2
3
public Optional<Customer> findCustomerWithSSN(String ssn) {
    ...
}

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

Это означает, что вызывающая метод явно вынуждена системой типов думать и иметь дело с возможностью того, что не может быть клиент с этим SSN.

Звонившему придется что-то вроде этого:

1
2
3
4
5
6
7
8
9
Optional<Customer> optional = findCustomerWithSSN(ssn);
 
if (optional.isPresent()) {
    Customer customer = maybeCustomer.get();
    ... use customer ...
}
else {
    ... deal with absence case ...
}

Или в противном случае укажите значение по умолчанию:

1
Long value = findOptionalLong(ssn).orElse(0L);

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

Что Факультативно пытается решить?

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

Если бы Optional существовал с самого начала, большинство библиотек и приложений, скорее всего, справились бы с отсутствующими возвращаемыми значениями, уменьшив количество исключений нулевого указателя и общее количество ошибок в целом.

Как следует использовать Optional тогда?

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

Это цитата из списка рассылки OpenJDK :

«JSR-335 EG чувствовал довольно сильно, что Optional не должен быть включен больше, чем необходимо для поддержки только идиомы опционального возврата.

Кто-то предложил, может быть, даже переименовать его в OptionalReturn »

В контексте разработки драйвера домена это означает, что Optional должен использоваться в качестве возвращаемого типа определенных методов службы, репозитория или утилиты, таких как приведенный выше.

Что опционально не пытается решить

Необязательно, это не механизм, позволяющий избежать всех типов нулевых указателей. Обязательные входные параметры методов и конструкторов еще предстоит проверить, например.

Как и при использовании null, Optional не помогает передать значение отсутствующего значения. Подобным образом, значение null может означать много разных вещей (значение не найдено и т. Д.), Так же как и отсутствующее необязательное значение.

Вызывающий метод все равно должен проверить javadoc метода для понимания значения отсутствующего Optional, чтобы правильно с ним справиться.

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

Что не так с возвратом нуля?

Проблема в том, что вызывающая функция могла не прочитать javadoc для метода и забыть об обработке нулевого регистра.

Это происходит часто и является одной из основных причин исключений нулевого указателя, хотя и не единственной.

Как необязательно НЕ использовать?

Optional не предназначен для использования в этих контекстах, так как он ничего не купит:

  • в слое модели предметной области (не сериализуемо)
  • в DTO (по той же причине)
  • во входных параметрах методов
  • в параметрах конструктора

Как Optional помогает с функциональным программированием?

В вызовах связанных функций Optional предоставляет метод ifPresent() , который позволяет ifPresent() функции, которые могут не возвращать значения:

1
findCustomerWithSSN(ssn).ifPresent(() -> System.out.println("customer exists!"));

Полезные ссылки

Этот пост в блоге от Oracle идет дальше в Optional и использует его, сравнивая с аналогичной функциональностью в других языках — Устали от исключений нулевого указателя?

Этот шпаргалка содержит подробный обзор Факультативного — Факультативного в Java 8 Шпаргалки .

Ссылка: Java 8 Необязательно: как использовать его от нашего партнера JCG Алексея Новика в блоге The JHades Blog .