Перейти к основному содержимому

Что вызывает java.lang.reflect.InvocationTargetException?

· 2 мин. чтения

1. Обзор

При работе с Java Reflection API часто встречается java.lang.reflect.InvocationTargetException .

В этом уроке мы рассмотрим это и как с этим справиться на простом примере .

2. Причина InvocationTargetException

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

Слой отражения оборачивает фактическое исключение, созданное методом, с помощью InvocationTargetException .

Попробуем понять это на примере.

Мы напишем класс с методом, который намеренно выдает исключение:

public class InvocationTargetExample {
public int divideByZeroExample() {
return 1 / 0;
}
}

Давайте вызовем вышеуказанный метод, используя отражение в простом тесте JUnit 5:

InvocationTargetExample targetExample = new InvocationTargetExample(); 
Method method =
InvocationTargetExample.class.getMethod("divideByZeroExample");

Exception exception =
assertThrows(InvocationTargetException.class, () -> method.invoke(targetExample));

В приведенном выше коде мы установили InvocationTargetException , которое возникает при вызове метода. Здесь важно отметить, что фактическое исключение — в данном случае ArithmeticException — заворачивается в InvocationTargetException .

Теперь, почему отражение не выдает фактическое исключение в первую очередь?

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

3. Как обрабатывать исключение InvocationTargetException ?

Здесь фактическое основное исключение является причиной InvocationTargetException , поэтому мы можем использовать Throwable.getCause() , чтобы получить больше информации об этом.

Давайте посмотрим, как мы можем использовать getCause() для получения фактического исключения в том же примере, что и выше:

assertEquals(ArithmeticException.class, exception.getCause().getClass());

Мы использовали метод getCause() для того же объекта исключения , который был сгенерирован. И мы заявили ArithmeticException.class как причину исключения.

Таким образом, как только мы получим базовое исключение, мы можем повторно сгенерировать его, обернуть его в какое-либо пользовательское исключение или просто зарегистрировать исключение в соответствии с нашим требованием.

4. Вывод

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

Мы также увидели, как определить основную причину InvocationTargetException и как справиться с таким сценарием на простом примере.

Как обычно, код, использованный в этой статье, доступен на GitHub .