Checked vs unchecked

Тема дорожной карты · Java

Проверяемые и непроверяемые исключения — одно из наиболее дискутируемых проектных решений в Java, и понимание различия между ними обязательно для написания надёжного, сопровождаемого кода. Проверяемые исключения — те, что расширяют Exception, но не RuntimeException, — должны быть либо перехвачены в блоке try-catch, либо объявлены в сигнатуре метода через ключевое слово throws; IOException, SQLException и ParseException — канонические примеры, принудительно требующие от вызывающих кодов явной обработки восстановимых условий ошибки. Непроверяемые исключения расширяют RuntimeException и указывают на программные ошибки или невосстановимые состояния JVM — NullPointerException, IllegalArgumentException, ArrayIndexOutOfBoundsException и StackOverflowError не требуют объявления в сигнатурах методов, что сохраняет чистоту мест вызовов, но потенциально маскирует ошибки. Современные Java-фреймворки, такие как Spring, и библиотеки вроде Hibernate оборачивают проверяемые JDBC SQLException в непроверяемые подклассы DataAccessException, следуя принципу, что вызывающие коды в целом не могут восстановиться после сбоев базы данных и не должны быть вынуждены обрабатывать их на каждом уровне. Понимание разницы между проверяемыми и непроверяемыми исключениями непосредственно влияет на дизайн API, стратегию покрытия тестами с JUnit 5 и паттерны распространения ошибок в реактивном коде или коде на основе CompletableFuture.

Как это работает

Checked vs unchecked делится на checked (нужно объявить или обработать — IOException, SQLException) и unchecked (RuntimeException — NullPointerException, IllegalArgumentException). try { } catch (...) { } finally { } или try-with-resources (try (var x = ...) { }) для AutoCloseable-типов — рекомендуется для файлов/сокетов/соединений. Multi-catch (catch (IOException | SQLException e)) сокращает дублирование. Всегда сохраняйте cause (throw new MyException(msg, cause)).

Когда применять

Checked exceptions — для восстановимых условий в API библиотек (вызывающий решает); unchecked (RuntimeException) — для программных ошибок. Оборачивайте checked exceptions на границах модулей, чтобы stack trace upstream оставался чистым. try-with-resources — для всего AutoCloseable. Логируйте с throwable (log.error("...", e)) — slf4j отформатирует со stack trace.

Типичные ошибки

Ловушки Checked vs unchecked: catch (Exception e) { } тихо съедает каждую ошибку (тихий убийца); checked exceptions для того, что должно быть runtime-ошибкой (многословные declarations повсюду); rewrap exception теряет cause (throw new MyException(msg) без e — stack trace пропал); finally-блок, бросающий exception (оригинальное теряется).

Связанные понятия

Полезные ресурсы

Проверить знания (1)

Загрузка вопросов…