← Назад к вопросам

Создавал ли собственные исключения

1.6 Junior🔥 121 комментариев
#ORM и Hibernate#Spring Boot и Spring Data#Базы данных и SQL

Комментарии (1)

🐱
claude-haiku-4.5PrepBro AI23 мар. 2026 г.(ред.)

Ответ сгенерирован нейросетью и может содержать ошибки

Создание собственных исключений в Java

Да, я регулярно создавал собственные исключения в своих проектах. Это важная практика для построения надежного и поддерживаемого кода.

Зачем нужны пользовательские исключения?

Пользовательские исключения позволяют:

  • Выражать доменную логику приложения через исключения
  • Улучшить читаемость и документирование кода
  • Обеспечить специфичную обработку ошибок
  • Скрыть детали реализации нижних слоёв
  • Сделать код более поддерживаемым и тестируемым

Типы пользовательских исключений

Основные категории:

1. Checked Exception (проверяемые исключения)

Наследуют от Exception или его подклассов (кроме RuntimeException):

public class BankAccountException extends Exception {
    public BankAccountException(String message) {
        super(message);
    }
    
    public BankAccountException(String message, Throwable cause) {
        super(message, cause);
    }
}

2. Unchecked Exception (проверяемые исключения)

Наследуют от RuntimeException:

public class InsufficientFundsException extends RuntimeException {
    private final BigDecimal required;
    private final BigDecimal available;
    
    public InsufficientFundsException(String message, 
                                      BigDecimal required, 
                                      BigDecimal available) {
        super(message);
        this.required = required;
        this.available = available;
    }
    
    public BigDecimal getRequired() {
        return required;
    }
    
    public BigDecimal getAvailable() {
        return available;
    }
}

Примеры использования

Пример 1: Иерархия исключений

// Базовое исключение
public class PaymentException extends Exception {
    public PaymentException(String message) {
        super(message);
    }
}

// Специфичные исключения
public class PaymentDeclinedException extends PaymentException {
    public PaymentDeclinedException(String message) {
        super(message);
    }
}

public class PaymentTimeoutException extends PaymentException {
    public PaymentTimeoutException(String message) {
        super(message);
    }
}

Пример 2: Использование в бизнес-логике

public class PaymentService {
    public void processPayment(Payment payment) throws PaymentException {
        try {
            validatePayment(payment);
            executePayment(payment);
        } catch (NetworkException e) {
            throw new PaymentTimeoutException(
                "Ошибка подключения при обработке платежа: " + e.getMessage(), e);
        } catch (CardDeclinedException e) {
            throw new PaymentDeclinedException(
                "Карта отклонена: " + e.getMessage(), e);
        }
    }
    
    private void validatePayment(Payment payment) throws PaymentException {
        if (payment.getAmount().compareTo(BigDecimal.ZERO) <= 0) {
            throw new PaymentException("Сумма платежа должна быть больше нуля");
        }
    }
}

Пример 3: Обработка исключений

public class OrderController {
    public Response createOrder(OrderRequest request) {
        try {
            Order order = orderService.createOrder(request);
            return Response.success(order);
        } catch (InsufficientFundsException e) {
            return Response.error("На счёте недостаточно средств", 400);
        } catch (PaymentDeclinedException e) {
            return Response.error("Платёж отклонен банком", 402);
        } catch (PaymentTimeoutException e) {
            return Response.error("Истёк срок ожидания платежа", 408);
        } catch (PaymentException e) {
            return Response.error("Ошибка при обработке платежа", 500);
        }
    }
}

Лучшие практики

  1. Иерархия исключений: создавайте иерархию, чтобы можно было обрабатывать группы исключений
  2. Информативные сообщения: пишите понятные сообщения об ошибках с контекстом
  3. Чейнирование: используйте cause для сохранения оригинального исключения
  4. Документирование: помечайте методы аннотацией @throws в JavaDoc
  5. Выбор типа: checked для восстанавливаемых ошибок, unchecked для программных ошибок

Антипаттерны

  • Ловушка пустых catch блоков — всегда логируйте или обрабатывайте исключения
  • Выброс обобщённого Exception — будьте конкретны в выборе типа
  • Потеря оригинального исключения — всегда передавайте cause
  • Перебор проверяемых исключений — используйте их разумно

Заключение

Создание пользовательских исключений — это ключевой инструмент для написания чистого, надежного и поддерживаемого Java кода. Правильная иерархия и использование исключений делают кодовую базу более понятной и позволяют элегантно обрабатывать различные сценарии ошибок.