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 .