«1. Обзор

Ключевое слово throw в Java используется для явного создания пользовательского или встроенного исключения. Но иногда в блоке catch нам нужно снова вызвать то же самое исключение. Это приводит к повторному созданию исключения.

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

2. Повторное создание исключений

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

Мы можем выполнить такие действия в блоке catch и снова создать исключение. Таким образом, более высокий уровень получает уведомление о том, что в системе произошло исключение.

Давайте разберем наш случай на примере.

Ниже мы повторно выбрасываем одно и то же исключение. И мы записываем сообщение об ошибке непосредственно перед его генерацией:

String name = null;

try {
    return name.equals("Joe"); // causes NullPointerException
} catch (Exception e) {
    // log
    throw e;
}

Консоль покажет следующее сообщение:

Exception in thread "main" java.lang.NullPointerException
  at com.baeldung.exceptions.RethrowSameExceptionDemo.main(RethrowSameExceptionDemo.java:16)

Как мы видим, наш код просто повторно генерирует любое исключение, которое он перехватывает. Из-за этого мы получаем исходную трассировку стека без каких-либо изменений.

3. Обтекание исключений

Теперь давайте рассмотрим другой подход.

В этом случае мы передадим то же исключение в качестве ссылки в конструкторе другого исключения:

String name = null;

try {
    return name.equals("Joe"); // causes NullPointerException
} catch (Exception e) {
    // log
    throw new IllegalArgumentException(e);
}

Консоль отобразит:

Exception in thread "main" java.lang.IllegalArgumentException: java.lang.NullPointerException
  at com.baeldung.exceptions.RethrowDifferentExceptionDemo.main(RethrowDifferentExceptionDemo.java:24)
Caused by: java.lang.NullPointerException
  at com.baeldung.exceptions.RethrowDifferentExceptionDemo.main(RethrowDifferentExceptionDemo.java:18)

На этот раз мы видим исходное исключение а также обертывающий. Таким образом, наш экземпляр IllegalArgumentException оборачивает исходное исключение NullPointerException в качестве причины. Следовательно, мы можем показать более конкретное исключение вместо общего.

4. Заключение

В этой короткой статье мы представили основное различие между повторным генерированием исходного исключения и его первой оболочкой. Оба способа отличаются друг от друга способом отображения сообщения об исключении.

Исходя из нашего требования, мы можем либо повторно генерировать одно и то же исключение, либо обернуть его каким-то конкретным исключением, используя второй подход. Второй подход выглядит чище и упрощает откат исключения.

Как всегда, проект доступен на GitHub.