Карта / Исключения / checked vs unchecked

checked vs unchecked

  • Error — фатальные сбои JVM (OutOfMemoryError, StackOverflowError). Их не ловят — это не твоя зона ответственности.
  • Checked (наследники Exception, кроме RuntimeException) — компилятор заставляет обработать или объявить в throws. Это «ожидаемые внешние проблемы»: файла нет (IOException), база недоступна (SQLException).
  • Unchecked (RuntimeException и наследники) — компилятор не заставляет. Это «ошибки программиста»: NullPointerException, IllegalArgumentException, ArrayIndexOutOfBoundsException.
void readFile() throws IOException {   // checked — обязан объявить или поймать
    Files.readString(Path.of("file.txt"));
}
Копнуть глубже

Современная практика — unchecked повсюду. Когда добавляли checked исключения в Java, казалось хорошей идеей заставить программиста их обрабатывать. На практике это привело к «exception pollution»: методы вынуждены объявлять throws SQLException в сигнатурах на всех уровнях, хотя не умеют их обработать — только прокидывают дальше. Поэтому Spring, Hibernate, JUnit и большинство современных фреймворков оборачивают checked в unchecked:

// Hibernate ловит SQLException и бросает RuntimeException
try {
    // SQL
} catch (SQLException e) {
    throw new DataAccessException("query failed", e);  // unchecked
}
// вызывающий код чистый — не нужно try-catch везде

Когда checked всё же оправдан. IOException при работе с файлами — разумный выбор: это реально ожидаемая внешняя ошибка, которую программа должна уметь обработать (файл не найден — пользователь должен выбрать другой). Но SQLException у ORM — плохой выбор: обрабатывать её в бизнес-коде бессмысленно.

🎤 Закрыл тему, если можешь объяснить:
• чем checked исключения отличаются от unchecked и почему `Error` не ловят.