Какво причинява 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.