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.