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

В Java предусмотрены встроенные исключения, такие как NullPointerException, ArithmeticException, IOException и другие. Однако в реальных приложениях часто возникают ситуации, когда нужно создавать собственные (пользовательские) исключения для обработки специфических ошибок.
Пользовательские исключения позволяют сделать код более читаемым и удобным для отладки.

Зачем создавать пользовательские исключения?
  1. Семантика: Пользовательские исключения позволяют точно описать тип ошибки.

  2. Гибкость: Можно добавлять дополнительные поля и методы для хранения информации об ошибке.

  3. Удобство: Упрощает отладку и обработку ошибок в больших проектах.


Иерархия пользовательских исключений
  • Пользовательские исключения создаются путем наследования от классов Exception или RuntimeException.

    • Если исключение должно быть проверяемым (checked), наследуйтесь от Exception.

    • Если исключение должно быть непроверяемым (unchecked), наследуйтесь от RuntimeException.


Создание пользовательского исключения

  1. Создайте класс, который наследуется от Exception или RuntimeException.

  2. Добавьте конструкторы:

    • Конструктор по умолчанию.

    • Конструктор с сообщением об ошибке.

    • Конструктор с сообщением и причиной (для цепочки исключений).

  3. При необходимости добавьте дополнительные поля и методы.

Пример создания пользовательского исключения
// Пользовательское проверяемое исключение class MyCheckedException extends Exception { // Конструктор по умолчанию public MyCheckedException() { super(); } // Конструктор с сообщением public MyCheckedException(String message) { super(message); } // Конструктор с сообщением и причиной public MyCheckedException(String message, Throwable cause) { super(message, cause); } } // Пользовательское непроверяемое исключение class MyUncheckedException extends RuntimeException { // Конструктор по умолчанию public MyUncheckedException() { super(); } // Конструктор с сообщением public MyUncheckedException(String message) { super(message); } // Конструктор с сообщением и причиной public MyUncheckedException(String message, Throwable cause) { super(message, cause); } }

Использование пользовательских исключений
  1. Проверяемое исключение:

    • Должно быть обработано с помощью try-catch или объявлено в сигнатуре метода с помощью throws.

    • public void processData() throws MyCheckedException { if (someCondition) { throw new MyCheckedException("Ошибка обработки данных"); } }
  2. Непроверяемое исключение:

    • Не требует обязательной обработки.

    • public void validateInput(String input) { if (input == null) { throw new MyUncheckedException("Входные данные не могут быть null"); } }

Иногда в пользовательских исключениях нужно хранить дополнительную информацию об ошибке. Например, код ошибки.

Пример с дополнительными полями
class CustomException extends Exception { private int errorCode; // Конструктор с сообщением и кодом ошибки public CustomException(String message, int errorCode) { super(message); this.errorCode = errorCode; } // Геттер для кода ошибки public int getErrorCode() { return errorCode; } }
Использование
try { throw new CustomException("Ошибка подключения к базе данных", 500); } catch (CustomException e) { System.out.println("Сообщение: " + e.getMessage()); System.out.println("Код ошибки: " + e.getErrorCode()); }

Цепочка исключений
  • В Java можно связывать исключения, чтобы сохранить информацию о первоначальной причине ошибки.

  • Для этого используется конструктор с параметром Throwable.

Пример:
try { // Код, который может вызвать исключение } catch (IOException e) { throw new CustomException("Ошибка ввода-вывода", e); }

Пример: Приложение для обработки заказов

Описание задачи:

Мы создадим простое приложение для обработки заказов. Если заказ имеет некорректный ID (например, отрицательный или равный нулю), программа должна выбрасывать пользовательское исключение OrderProcessingException.

Код приложения:
// Пользовательское исключение для обработки ошибок, связанных с заказами class OrderProcessingException extends Exception { // Конструктор с сообщением об ошибке public OrderProcessingException(String message) { super(message); } } // Класс, представляющий заказ class Order { private int orderId; // ID заказа // Конструктор для создания заказа с указанным ID public Order(int orderId) { this.orderId = orderId; } // Метод для обработки заказа public void process() throws OrderProcessingException { // Проверка корректности ID заказа if (orderId <= 0) { // Если ID некорректен, выбрасываем исключение throw new OrderProcessingException("Некорректный ID заказа: " + orderId); } // Логика обработки заказа (в данном примере не реализована) System.out.println("Заказ с ID " + orderId + " успешно обработан."); } } // Основной класс приложения public class Main { public static void main(String[] args) { // Создаем заказ с некорректным ID (например, -1) Order order = new Order(-1); try { // Пытаемся обработать заказ order.process(); } catch (OrderProcessingException e) { // Если возникло исключение, выводим сообщение об ошибке System.out.println("Ошибка обработки заказа: " + e.getMessage()); } } }
Пояснения к коду
  1. Пользовательское исключение OrderProcessingException:

    • Наследуется от Exception, что делает его проверяемым исключением.

    • Имеет конструктор, который принимает сообщение об ошибке и передает его в родительский класс.

  2. Класс Order:

    • Содержит поле orderId, которое хранит идентификатор заказа.

    • Конструктор Order(int orderId) инициализирует это поле.

    • Метод process() проверяет корректность orderId. Если ID некорректен (меньше или равен нулю), выбрасывается исключение OrderProcessingException.

  3. Класс Main:

    • В методе main создается объект Order с некорректным ID (-1).

    • Вызов метода process() обернут в блок try-catch, чтобы обработать возможное исключение.

    • Если исключение возникает, программа выводит сообщение об ошибке.

Пример работы программы

Входные данные:
  • Создается заказ с ID = -1.

Вывод программы:
Ошибка обработки заказа: Некорректный ID заказа: -1
Пояснение:
  • Поскольку ID заказа равен -1, метод process() выбрасывает исключение OrderProcessingException.

  • Исключение перехватывается в блоке catch, и выводится сообщение об ошибке.


Рекомендации

  1. Именование: Имена пользовательских исключений должны заканчиваться на Exception (например, InvalidInputException).

  2. Логирование: Всегда логируйте исключения для упрощения отладки.

  3. Минимизация: Не создавайте избыточное количество пользовательских исключений. Используйте их только там, где это действительно необходимо.


Комментарии

Добавить комментарий

Чтобы оставить комменатрий необходимо Авторизоваться