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().