Что вызывает исключение java.lang.reflect.InvocationTargetException?

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.