Optional
Optional явно говорит: результата может не быть
Метод иногда не может найти значение. Возврат null передаёт эту информацию неявно:
вызывающий код должен помнить о проверке сам. Optional<T>
делает отсутствие результата частью типа возвращаемого значения.
Optional<String> findName(int id) {
if (id == 1) {
return Optional.of("Alice");
}
return Optional.empty();
}
Optional.of(value) используется для гарантированно ненулевого значения,
Optional.ofNullable(value) принимает и null,
а Optional.empty() создаёт пустой результат.
Работай со значением через операции Optional
Вместо ручной схемы «проверить — достать — преобразовать»
часто удобнее продолжить вычисление через map, filter
и flatMap.
Optional<Integer> length = findName(1)
.filter(name -> !name.isBlank())
.map(String::length);
Если имя существует и не пустое, получится Optional с длиной.
Если значение отсутствовало или не прошло фильтр, результат останется пустым.
Значение по умолчанию или исключение
orElse возвращает запасное значение,
orElseGet вычисляет его через Supplier только при необходимости,
а orElseThrow сообщает об отсутствии значения исключением.
String name = findName(10)
.orElse("Unknown");
Если создание запасного значения дорогое или имеет побочный эффект,
обычно выбирают orElseGet:
аргумент orElse вычисляется ещё до вызова метода,
даже когда значение внутри Optional уже есть.
Не превращай Optional обратно в скрытый null
Метод get() существует, но прямой вызов без гарантии наличия значения
возвращает нас к той же проблеме: теперь вместо NullPointerException
можно получить NoSuchElementException.
Обычно намерение лучше выражают orElse, orElseThrow,
ifPresent или цепочка преобразований.
Optional особенно полезен как возвращаемый тип метода.
Это не универсальная замена каждому null в программе,
а способ явно сообщить вызывающему коду: «результат здесь может отсутствовать».