1.在通过反射执行方法的时,如Method.invoke(),如果被反射执行的方法体抛出了Exception,这个异常会被包装成InvocationTargetException重新抛出,下面是jdk里面的源码:
- public Object invoke(Object obj, Object... args)
- ows <span style="color: #ff0000;">IllegalAccessException</span>, IllegalArgumentException,
- InvocationTargetException
- {
- ...........此处省略.....
- }
比如反射方法里抛出了NullPointException,则Method.invoke方法抛出的是InvocationTargetException,而不是NullPointException,见下面的例子,此处抛出的就是InvocationTargetException。
但是InvocationTargetException太过于宽泛,在trouble shouting的时候,不能给人非常直观的信息,所以在处理反射方法异常的时候,我们需要把这个InvocationTargetException的targetException提取处理,重新抛出,因为这个才是对我们分析程序bug真正有帮助的异常:
- public class InvokeException {
- @SuppressWarnings("null")
- public void testException(){
- String nullString = null;
- nullString.toString();
- }
- public static void main(String[] args) throws Throwable {
- // TODO Auto-generated method stub
- try{
- InvokeException invokeException = new InvokeException();
- Method method = invokeException.getClass().getMethod("testException");
- method.invoke(invokeException);
- }catch (Exception e) {
- if(e instanceof InvocationTargetException){
- throw ((InvocationTargetException) e).getTargetException();
- }else{
- //doXXX()
- }
- }
- }
- }
结论: 在利用 Method 对象的 invoke 方法调用目标对象的方法时, 若在目标对象的方法内部抛出异常, 会抛出 InvocationTargetException 异常, 该异常包装了目标对象的方法内部抛出异常, 可以通过调用 InvocationTargetException 异常类的的
getTargetException() 方法得到原始的异常.