Комментарии (1)
🐱
claude-haiku-4.5PrepBro AI22 мар. 2026 г.(ред.)
Ответ сгенерирован нейросетью и может содержать ошибки
Ответ на вопрос о Checked Custom Exception
Можно ли создать Checked Custom Exception?
Да, можно и нужно создавать Checked Custom Exception. Это стандартный механизм в Java для обработки ошибок, которые может обработать код.
Создание простой Checked Exception
public class PaymentException extends Exception {
public PaymentException(String message) {
super(message);
}
public PaymentException(String message, Throwable cause) {
super(message, cause);
}
}
Ключевая разница: наследуем Exception (не RuntimeException)!
Обязательная обработка
Что отличает Checked от Unchecked:
public class AuthService {
public void login(String username, String password)
throws PaymentException { // throws ОБЯЗАТЕЛЕН
if (!isValid(username, password)) {
throw new PaymentException("Invalid credentials");
}
}
}
// Вызывающий код ДОЛЖЕН обработать
try {
authService.login("user", "pass");
} catch (PaymentException e) {
System.out.println("Ошибка: " + e.getMessage());
}
Checked vs Unchecked
| Тип | Наследует | Обработка | Когда использовать |
|---|---|---|---|
| Checked | Exception | Обязательна | Восстанавливаемые ошибки (DB, сеть) |
| Unchecked | RuntimeException | Опциональна | Баги, логические ошибки |
Пример с дополнительным контекстом
public class InvalidCredentialsException extends Exception {
private final String username;
private final LocalDateTime attemptTime;
public InvalidCredentialsException(String message, String username) {
super(message);
this.username = username;
this.attemptTime = LocalDateTime.now();
}
public String getUsername() { return username; }
public LocalDateTime getAttemptTime() { return attemptTime; }
}
Иерархия исключений
// Базовое исключение
public class DatabaseException extends Exception {}
// Специфичные
public class ConnectionException extends DatabaseException {}
public class QueryException extends DatabaseException {}
public class ConstraintViolationException extends DatabaseException {}
// Использование
public void createUser(User user) throws DatabaseException {
try {
// Логика
} catch (SQLException e) {
if (e.getMessage().contains("UNIQUE")) {
throw new ConstraintViolationException("Email уже существует");
}
throw new QueryException("Ошибка запроса");
}
}
// Обработка иерархии
try {
userRepository.createUser(user);
} catch (ConstraintViolationException e) {
System.out.println("Пользователь уже существует");
} catch (ConnectionException e) {
System.out.println("БД недоступна");
} catch (DatabaseException e) {
System.out.println("Неизвестная ошибка");
}
REST API пример
public class ResourceNotFoundException extends Exception {
private final String resourceType;
private final Object resourceId;
public ResourceNotFoundException(String resourceType, Object resourceId) {
super(resourceType + " не найден: " + resourceId);
this.resourceType = resourceType;
this.resourceId = resourceId;
}
}
@RestController
public class OrderController {
@GetMapping("/orders/{id}")
public Order getOrder(@PathVariable Long id) throws ResourceNotFoundException {
Order order = orderService.getOrderById(id);
if (order == null) {
throw new ResourceNotFoundException("Order", id);
}
return order;
}
}
Лучшие практики
1. Информативное имя
- ✅ PaymentException, NetworkTimeoutException
- ❌ MyException, BadException
2. Добавляйте контекст
- ✅ Дополнительные поля (user, orderId, amount)
- ❌ Только message
3. Поддерживайте конструкторы
- ✅ message и message + cause
- ❌ Только один конструктор
4. Создавайте иерархию
DatabaseException (базовая)
├── ConnectionException
├── QueryException
└── ConstraintViolationException
5. Используйте для восстанавливаемых ошибок
- ✅ DB error, network timeout, invalid input
- ❌ NullPointerException, IndexOutOfBoundsException
Когда использовать
Checked Exception:
- Ошибки БД
- Сетевые ошибки
- Ошибки файловой системы
- Валидация данных
- Бизнес-логика (неверный статус)
Unchecked Exception:
- Баги в коде
- Логические ошибки
- Нарушение контракта (null где не должен быть)
- Системные ошибки
Резюме
- Да, можно создавать - наследуя Exception
- Обязательно обрабатывать - throws или try-catch
- Добавляйте контекст - дополнительная информация об ошибке
- Создавайте иерархию - лучше обработка
- Информативные имена - понятно, что пошло не так
- Это правильный инструмент - для восстанавливаемых ошибок в production коде