2011-05-16 169 views
242

嗯,我试图理解和读到的东西可能会导致它,但我只是无法得到它:什么可能导致java.lang.reflect.InvocationTargetException?

我有我的代码某处这样的:

try{ 
.. 
m.invoke(testObject); 
.. 
} catch(AssertionError e){ 
... 
} catch(Exception e){ 
.. 
} 

的事情是,当它试图调用它抛出的某些方法 InvocationTargetException而不是某些其他预期的异常(具体为ArrayIndexOutOfBoundsException)。 正如我真的知道调用什么方法,我直接去了这个方法代码,并添加了一个try-catch块,假设这个代码块会抛出ArrayIndexOutOfBoundsException,并且它真的按照预期投掷了ArrayIndexOutOfBoundsException。然而,当它上涨时 以某种方式改变为InvocationTargetException并且在上面的代码中catch(Exception e) e是InvocationTargetException而不是ArrayIndexOutOfBoundsException 如预期的那样。

什么会导致这样的行为,或者我该如何检查这样的事情?

回答

263

您已通过调用具有反射的方法添加了一个额外的抽象级别。反射层包含InvocationTargetException中的任何异常,它允许您分辨异常实际上与反射调用中的失败(例如,您的参数列表无效)导致的异常以及调用的方法中的失败。

只需打开InvocationTargetException内的原因,就可以达到原来的原因。

+0

谢谢,但是我会怎样区分(AssertionError e)和(Exception e)?如果我在展开原因之前总是首先得到InvocationTargetException,那么每个异常之间的区别在哪里? – user550413 2011-05-16 17:32:51

+3

@ user550413:当然,解开异常并检查它。你可以随时扔掉它,如果必须的话就可以用它来捕捉它。 – 2011-05-16 17:53:21

+119

对于任何人想知道“在InvocationTargetException中解开原因”是什么意思,我只是发现如果你使用'exception.printStackTrace()'打印它,你只需看看“Caused By:”而不是上半部分/正常部分。 – Jan 2012-02-10 19:42:39

16

从Method.invoke的Javadoc中()

抛出:的InvocationTargetException - 如果底层方法抛出异常。

如果调用的方法抛出异常,则会引发此异常。

+0

所以想象一下,我有一个'java.lang.reflect.Proxy'实例级联,用于扩充一个包装对象。每个'Proxy'通过使用自己的'InvocationHandler'来优雅地处理特定的异常(可能由被包装的对象抛出)。对于通过这个级联直到到达正确的调用处理程序/代理的异常,在每个“InvocationHandler”中,我会捕获“InvocationTargetException”,解开它,检查包装的异常是否是由此处理的异常“instanceof” 'InvocationHandler'。如果它不是'instanceof',我会抛出** unwrapped **异常......对吧? – Abdull 2013-02-25 15:07:30

+0

我总是会抛出未包装的异常。 – 2013-03-05 23:02:59

39

的抛出异常如果

的InvocationTargetException - 如果底层方法抛出异常。

因此,如果该方法,已经被调用与反射API,将抛出异常(例如运行时异常),反射API将包裹该异常到InvocationTargetException

6

InvocationTargetException可能已经结束了你的ArrayIndexOutOfBoundsException。当使用反射方法可以抛出什么时,没有先知道 - 因此,而不是使用throws Exception方法,所有例外都被捕获并包装在InvocationTargetException中。

+0

谢谢,但是我会如何区别(AssertionError e)和(Exception e)?如果我在展开原因之前总是首先得到InvocationTargetException,那么每个异常之间的区别在哪里? – user550413 2011-05-16 17:38:15

31

InvocationTargetException上使用getCause()方法检索原始异常。

0
  1. 名单从Eclipse导航模式
  2. 所有jar文件确认所有jar文件在二进制模式
+2

如何通过在导航器中查看它们来验证jar文件是否处于二进制模式? – William 2013-01-24 20:48:37

1

This描述类似,

的InvocationTargetException是经过检查的异常该函数包装由调用的方法或构造函数抛出的 异常。从版本 1.4开始,此异常已被改进以符合通用异常链接机制。在构建时提供并通过 getTargetException()方法访问的“目标例外” 现在被称为原因,并且可能通过Throwable.getCause()方法以及 访问前述方法。”

0

如果底层方法(使用Reflection调用的方法)抛出异常,则会引发此异常。

因此,如果反射API调用的方法引发异常(例如运行时异常),则反射API将将该异常包装到InvocationTargetException中。

8

这将打印的准确代码行的具体方法,它被调用时,引发的异常:我做 洁净>运行xDoclet->运行xPackaging后

try { 

    // try code 
    .. 
    m.invoke(testObject); 
    .. 

} catch (InvocationTargetException e) { 

    // Answer: 
    e.getCause().printStackTrace(); 
} catch (Exception e) { 

    // generic exception handling 
    e.printStackTrace(); 
} 
+0

谢谢;这帮助我意识到我的问题不在反思本身,而是在被调用的方法中。 – 2017-01-30 11:33:01

-6

错误消失了。

在我的工作区中,在ecllipse中。

1

您可以使用的getCause()方法原始异常类这样的比较:

try{ 
    ... 
} catch(Exception e){ 
    if(e.getCause().getClass().equals(AssertionError.class)){ 
     // handle your exception 1 
    } else { 
     // handle the rest of the world exception 
    } 
} 
0

我面临同样的问题。我用e.getCause()。getCause()然后我发现它是因为我传递的参数错误。在获取其中一个参数的值时发生了nullPointerException。 希望这会帮助你。

0

我在外部classclass有来自呼叫记录对象语句的java.lang.reflect.InvocationTargetException错误try/catch块内。

通过Eclipse调试器&代码步进将鼠标悬停我看到了记录object记录仪的声明是null(需要在我class的最顶部被实例化一些外部常量)。

相关问题