Я опаздываю к игре, но за то, что она того стоит, я хочу добавить свои 2 цента. Они идут вразрез с целью разработкиOptional
, которая хорошо описана в ответе Стюарта Маркса , но я все еще убежден в их обоснованности (очевидно).
Использовать дополнительно везде
В основном
Я написал целую запись в блоге об использовании,Optional
но в основном это сводится к следующему:
- разработайте свои классы, чтобы избежать возможности, где это возможно
- во всех остальных случаях по умолчанию следует использовать
Optional
вместоnull
- возможно сделать исключения для:
- локальные переменные
- возвращать значения и аргументы в приватные методы
- блоки кода, критичные к производительности (без предположений, используйте профилировщик)
Первые два исключения могут уменьшить воспринимаемые накладные расходы на упаковку и развертывание ссылок в Optional
. Они выбраны так, что нуль никогда не может законно пройти границу из одного экземпляра в другой.
Обратите внимание, что это почти никогда не допустит Optional
s в коллекциях, что почти так же плохо, как null
s. Просто не делай этого. ;)
По поводу ваших вопросов
- Да.
- Если перегрузка не вариант, да.
- Если другие подходы (создание подклассов, декорирование, ...) не подходят, да.
- Пожалуйста, нет!
преимущества
Это уменьшает присутствие null
s в вашей кодовой базе, хотя и не уничтожает их. Но это даже не главное. Есть и другие важные преимущества:
Проясняет намерение
Использование Optional
четко выражает, что переменная, ну, необязательно. Любому читателю вашего кода или потребителю вашего API придется биться из-за того, что там ничего не может быть, и что необходима проверка перед доступом к значению.
Устраняет неопределенность
Без Optional
смысла null
происшествия неясно. Это может быть юридическое представление состояния (см. Map.get
) Или ошибка реализации, например, отсутствующая или неудачная инициализация.
Это резко меняется с постоянным использованием Optional
. Здесь уже появление null
означает наличие ошибки. (Потому что, если бы значение могло быть пропущено, использовался Optional
бы an .) Это значительно облегчает отладку исключения с нулевым указателем, поскольку на вопрос о значении этого null
уже дан ответ.
Больше нулевых проверок
Теперь, когда ничего не может быть null
больше , это можно применять везде. При использовании аннотаций, утверждений или простых проверок вам никогда не придется задумываться о том, может ли этот аргумент или тип возвращаемого значения быть нулевым. Это не может!
Недостатки
Конечно, нет серебряной пули ...
Производительность
Упаковка значений (особенно примитивов) в дополнительный экземпляр может снизить производительность. В тесных петлях это может стать заметным или даже хуже.
Обратите внимание, что компилятор может обойти дополнительную ссылку для кратковременного времени жизни Optional
s. В Java 10 типов значений могут дополнительно уменьшить или убрать штраф.
Сериализация
Optional
не сериализуем, но обходной путь не слишком сложен.
неизменность
Из-за неизменности универсальных типов в Java некоторые операции становятся громоздкими, когда фактический тип значения помещается в аргумент универсального типа. Пример приведен здесь (см. «Параметрический полиморфизм») .
Map<Character, String>
. Если нет никакой замены я могу использовать это:Optional.ofNullable(map.get(c)).orElse(String.valueOf(c))
. Также обратите внимание, что Optional был украден из Гуавы, и у него гораздо более приятный синтаксис:Optional.fromNullable(map.get(c)).or(String.valueOf(c));