Ответ
Выбор между checked (Exception) и unchecked (RuntimeException) для пользовательского исключения зависит от семантики ошибки и требований к обработке.
Критерии выбора
| Критерий | Checked исключение | Unchecked исключение |
|---|---|---|
| Восстановимость | Ошибка ожидаема, и есть разумная стратегия восстановления. | Ошибка критична или указывает на баг; восстановление маловероятно. |
| Обязательность обработки | Требуется явная обработка вызывающим кодом. | Обработка опциональна, часто приводит к остановке потока/запроса. |
| Причина | Внешние условия (отсутствующий файл, недоступный сервис). | Нарушение контракта/логики (неверный аргумент, недопустимое состояние). |
| Влияние на API | Усложняет сигнатуру метода (добавляет throws). |
Не влияет на сигнатуру метода. |
Примеры создания
1. Checked исключение (обязательная обработка условия):
// Ошибка, от которой можно попытаться восстановиться (например, повторить запрос)
public class ServiceUnavailableException extends Exception {
public ServiceUnavailableException(String message, Throwable cause) {
super(message, cause);
}
}
// Использование заставляет вызывающего решить, что делать при недоступности сервиса.
2. Unchecked исключение (ошибка программиста/валидации):
// Нарушение бизнес-правила, которое должно быть проверено до вызова метода
public class InsufficientFundsException extends RuntimeException {
public InsufficientFundsException(double balance, double required) {
super(String.format("Баланс %.2f недостаточен для списания %.2f", balance, required));
}
}
// Использование: выбрасывается, если сумма списания > баланса.
// Обработка глобальная (например, на уровне контроллера).
Современный best practice: В enterprise-приложениях чаще создают unchecked-исключения для бизнес-ошибок, обрабатывая их централизованно (например, через @ControllerAdvice в Spring). Checked оставляют для действительно recoverable-ошибок, часто на границах системы (DAO, внешние вызовы).