在使用 Java 反射 API 时,经常会遇到 Java 异常 java.lang.reflect.InvocationTargetException
。本节将介绍该 Java 异常是如何发生的,已经如何处理该异常。
发生 InvocationTargetException 原因
异常 java.lang.reflect.InvocationTargetException
主要发生在使用反射代码去调用方法,或者构造器本身出现异常时。
反射层使用 InvocationTargetException 包装原方法抛出的实际异常。
下面,通过一个例子来理解它,下面的类中存在一个会抛出异常的方法:
public class InvocationTargetExample {
public int divideByZeroExample() {
return 1 / 0;
}
}
接下来,利用反射来调用上述方法:
InvocationTargetExample targetExample = new InvocationTargetExample();
Method method = InvocationTargetExample.class.getMethod("divideByZeroExample");
Exception exception =
assertThrows(InvocationTargetException.class, () -> method.invoke(targetExample));
在上面的代码中,我们声明了异常InvocationTargetException
,它在调用该方法时抛出。这里要注意的重要一点是,实际异常(除零异常ArithmeticException)被包装到InvocationTargetException
中。
那么问题来了,为什么没有抛出实际的异常,而是给出反射异常呢?
原因是它使我们能够了解,Exception
是由于未能通过反射层调用方法而发生,还是在方法本身内部发生了。
如何处理 InvocationTargetException
实际导致 InvocationTargetException
的原因,可以通过 Throwable.getCause()
来获得。如果想得到上述例子中具体的异常信息,可以用下面的代码来测试:
assertEquals(ArithmeticException.class, exception.getCause().getClass());
在这里,我们在抛出的同一异常对象上使用了 getCause()
方法。并且断言ArithmeticException.class
是导致异常的原因。
只要能获得基础异常,就可以重新抛出该异常,将其包装在一些自定义异常中,或者根据需求简单地记录该异常,放入 log 中。