Необязательный, представленный в Java в версии 8, часто используется неправильно. Устранение пустых значений не является целью Optional.

Основная цель разработки Optional - использовать его в качестве возвращаемого значения библиотечного метода функций, когда возвращаемое значение может отсутствовать. Намерение состоит в том, чтобы вызывающий объект немедленно проверял Optional и извлекал фактическое значение, если оно присутствует. Если значение отсутствует, вызывающий может заменить значение по умолчанию, вызвать исключение или применить другую политику. Обычно это делается путем объединения вызовов свободных методов в конце конвейера потока (или других методов), которые возвращают необязательные значения.

Давайте обсудим, где не использовать optional:

Места, которые нельзя использовать Необязательно

Избегайте использования Optional в параметрах метода

С параметром Optional вы переходите от двух возможных входов: null и ненулевое значение к трем: null, ненулевое значение без значения и ненулевое значение со значением. Добавьте к этому тот факт, что уже давно доступна перегрузка, чтобы сообщить, что некоторые параметры являются необязательными, и на самом деле нет причин иметь Optional параметров. Инструменты анализа кода, такие как SonarQube и IntelliJ. Флаг Необязательный в параметрах метода как основной запах кода (RSPEC-3553).

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

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

foo("bar", Optional.of("baz"));
foo("bar", Optional.empty());

Даже принимать null лучше:

foo("bar", "baz");
foo("bar", null);

Вероятно, лучше всего иметь перегруженный метод, который принимает один строковый аргумент и предоставляет значение по умолчанию для второго:

foo("bar", "baz");
foo("bar");

У этого есть ограничения, но он намного приятнее любого из вышеперечисленных.

Избегайте использования необязательных в полях

Java Optional также не рекомендуется использовать в качестве полей в POJO. Java Optional не сериализуем, и если у вас действительно есть требование к необязательному полю, вы можете использовать поля, допускающие значение NULL, с получением, возвращающим Optional.

Избегайте использования Optional в коллекциях

Иногда люди хотят поместить Optional в коллекции, например List<Optional<X>> или Map<Key,Optional<Value>>. Это тоже обычно плохая идея. Может показаться, что это необходимо, чтобы различать отсутствие записи и нулевую запись. Часто лучше заменить такое использование Optional значениями Null-Object (не фактическими null ссылками) или просто полностью исключить эти записи из коллекции.

Объем памяти

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

Адаптация между нулевым и необязательным

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

• Если у вас есть ссылка, допускающая значение NULL, и вам нужен необязательный

Optional<T> opt = Optional.ofNullable(ref)

• Если у вас есть Optional и вам нужна ссылка, допускающая значение NULL

opt.orElse(null)

Необязательный не сериализуемый

Несмотря на то, что Guava Optional сериализуем, Java optional не сериализуема по дизайну.

Использование в Whatfix

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