Optional

Базовый Java
≈ 2 мин чтения

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 в программе, а способ явно сообщить вызывающему коду: «результат здесь может отсутствовать».