Gymterview
middle

Эволюция null-safety в Java

Java не имеет встроенной null-safety на уровне типов (в отличие от Kotlin ?), но постепенно добавляет инструменты: Optional (Java 8+), Helpful NPE (Java 14+), null в Pattern Matching (Java 21+), аннотации @Nullable/@NonNull.

Optional — эволюция API по версиям

Версия Новый API Описание
Java 8 Optional.of/ofNullable/empty Базовый Optional
Java 9 ifPresentOrElse(), or(), stream() Расширенный API
Java 10 orElseThrow() без аргументов Замена get()
Java 11 isEmpty() Инверсия isPresent()
Java 21 Pattern Matching + null в switch Альтернативный подход к null
Пример: эволюция Optional и null handling
// Java 8 — базовый Optional
Optional<String> name = Optional.ofNullable(user.getName());
String result = name.orElse("Unknown");

// Java 9 — ifPresentOrElse, or
optional.ifPresentOrElse(
    value -> process(value),
    () -> handleAbsence()
);
Optional<String> fallback = primary.or(() -> secondary);

// Java 10 — orElseThrow() без аргументов
String value = optional.orElseThrow(); // вместо optional.get()

// Java 11 — Optional.isEmpty()
if (optional.isEmpty()) { ... } // вместо !optional.isPresent()

// Java 21+ — Pattern Matching с null:
switch (value) {
    case null -> handleNull();
    case String s -> process(s);
    default -> other();
}

Helpful NullPointerException (Java 14+)

Пример
var street = user.getAddress().getCity().toUpperCase();
// До Java 14: NullPointerException (непонятно, что null)
// Java 14+:   Cannot invoke "City.toUpperCase()" because
//             the return value of "Address.getCity()" is null

Аннотации @Nullable / @NonNull

Пример
import org.springframework.lang.NonNull;
import org.springframework.lang.Nullable;

@NonNull
public User findById(@NonNull Long id) {
    return userRepository.findById(id)
        .orElseThrow(() -> new NotFoundException("User not found: " + id));
}

@Nullable
public User findByEmail(@NonNull String email) {
    return userRepository.findByEmail(email).orElse(null);
}

Частые ошибки

  • Optional как параметр метода — anti-pattern; используйте перегрузку методов или @Nullable
  • Optional как поле класса — Optional не Serializable; используйте @Nullable для полей
  • optional.get() без проверки — может бросить NoSuchElementException; используйте orElseThrow(), orElse(), ifPresent()
  • Игнорировать @Nullable аннотации — IDE подсвечивает потенциальные NPE; не игнорируйте warnings

Как используется в 2026

  • Optional — стандарт для возвращаемых значений (особенно в repository/service слоях)
  • @Nullable/@NonNull аннотации — best practice; Spring использует @NonNullApi для всего пакета
  • JSpecify (org.jspecify) — новый стандарт null-safety аннотаций, набирает популярность
  • Pattern Matching + null handling в switch — удобная обработка nullable значений

На собеседовании: покажите, что знаете правила использования Optional (возвращаемые значения — да, параметры и поля — нет), Helpful NPE для отладки, и аннотации для статического анализа. Частая ошибка — вызывать optional.get() без проверки вместо orElseThrow().