@beduin01

Зачем нужен Optional и почему над null нельзя выполнить те же действия?

Думаю тут язык не принципиален. Не могу понять, зачем был введен тип Optional? Что мешало над null все тоже выполнять?
ArrayList<Integer> numbers = new ArrayList<Integer>();
Optional<Integer> min = numbers.stream().min(Integer::compare);
if(min.isPresent()){
             
    System.out.println(min.get());
}


Потому что null это указатель, а не класс? Почему для него нельзя было isPresent реализовать?
  • Вопрос задан
  • 886 просмотров
Решения вопроса 1
@koperagen
Вы и так можете проверить проверить ссылку на null, без каких-то дополнительных методов и сущностей. Optional здесь явным образом сообщает, что результат метода может существовать (значение), либо не существовать (null) и не даёт получить значение, не сделав выбор, как обработать ситуацию с его отсутствием. Кроме обычного get() есть ещё методы getOrElse(), позволяющий указать значение по умолчанию, getOrNull().

Ещё бывает удобно сначала выполнить цепочку преобразований над Optional при помощи метода map(), а в конце получить значение любым удобным способом и дальше работать с "чистым" объектом ожидаемого типа.

В kotlinе (раз язык не принципиален) на помощь с борьбой с NPE приходят nullable типы. Каждый класс порождает два типа, к примеру для класса Person это будет Person и Person?. В сигнатурах методов можно явно указать, какой из типов допустим. Если Person?, то компилятор вынудит вас обработать случай с приходом null. Так же вы не сможете вернуть из метода null, если объявили в качестве результата тип Person. Программа просто не скомпилируется. Все ради того, чтобы null не приходил из неожиданных мест, обрабатывался и не ронял программу.
Ответ написан
Комментировать
Пригласить эксперта
Ответы на вопрос 3
doublench21
@doublench21
Концепция опционалов не нова и проста как банный лист. Это всего лишь перечисление(enum):
(Полную реализацию можно глянуть тут)

enum Optional<Wrapped>: ExpressibleByNilLiteral {
  // The compiler has special knowledge of Optional<Wrapped>, including the fact
  // that it is an `enum` with cases named `none` and `some`.
  /// The absence of a value.
  ///
  /// In code, the absence of a value is typically written using the `nil`
  /// literal rather than the explicit `.none` enumeration case.
  case none

  /// The presence of a value, stored as `Wrapped`.
  case some(Wrapped)

  /// Creates an instance that stores the given value.
  @_transparent
  public init(_ some: Wrapped) { self = .some(some) }

 //...


НО люди по своей природе не любят сложностей, даже если сама идея достаточно хорошо. Никто не хочет каждый раз писать Optional<MyClass>.some(myObj) и тому сопутствующее...

Тут та и на сцену выходит язык Swift, где концепция Опционалов выведена в абсолют и поддерживается на уровня компилятора. А что же это даёт? Достаточно много удобств: не нужно писать полный тип, добавили соответсвующие литералы("!", "?", "nil") и в целом работа с перечислением(enum Optional) сделана в виде обычного стандартного типа, Аля Int какой-нибудь.

---------------------------------------

Зачем нужен Optional и почему над null нельзя...?

Нельзя потому-что по своей природе null указывает на указатель который никуда не указывает в данный момент. Optional же позволяет растянуть эту концепцию не только на указатели(значит на ссылочные типы), но и на самые обычные типы(типы значения).
Ответ написан
Комментировать
briahas
@briahas
ObjC, Swift, Python
Вы ведь не можете налить борщ в слово "тарелка"? Вам нужен объект - тарелка.
Получается, в мозгу есть тип Optional который в себе соединяет слово (которое по сути не материально = null) и реальный объект/тип... С компилятором гдето +- все тоже самое.
(Немного фривольное объяснение, но думаю натолкнет на нужные мысли)
Ответ написан
mayton2019
@mayton2019 Куратор тега Java
Bigdata Engineer
В отличие SQL, Lisp и прочих технологий где null/nil имеет смысловую семантику и позволяет выполнять операции в Java любая попытка применить любой метод к null выбрасывает немедленный NPE. Это означает что программист ЗАБЫЛ инициалировать объект. Это грубая ошибка и самое печальное что она не чекается компиллятором. Использование Optional в стримах необходимо чтобы защитить применение map/filter от внезапного NPE.
Пример который привел автор в начале топика просто неудачен. Он не раскрывает преимуществ Optional. Смотрите статью на сайте Баелдунга. Она - более наглядная.
Ответ написан
Комментировать
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы