什么可能导致 java.lang.reflect.InvocationTargetException?
Posted
技术标签:
【中文标题】什么可能导致 java.lang.reflect.InvocationTargetException?【英文标题】:What could cause java.lang.reflect.InvocationTargetException? 【发布时间】:2011-08-26 14:47:55 【问题描述】:好吧,我试图理解并阅读可能导致它的原因,但我就是无法理解:
我的代码中有这个:
try
..
m.invoke(testObject);
..
catch(AssertionError e)
...
catch(Exception e)
..
事情是,当它试图调用某个方法时,它会抛出
InvocationTargetException
而不是其他一些预期的异常(特别是 ArrayIndexOutOfBoundsException
)。
因为我实际上知道调用了什么方法,所以我直接进入了这个方法代码,并为应该抛出 ArrayIndexOutOfBoundsException
的行添加了一个 try-catch 块,它确实像预期的那样抛出了 ArrayIndexOutOfBoundsException
。然而上去的时候
以某种方式更改为InvocationTargetException
和上面的代码catch(Exception e)
e 是 InvocationTargetException
而不是 ArrayIndexOutOfBoundsException
正如预期的那样。
什么可能导致这种行为或者我如何检查这种情况?
【问题讨论】:
我遇到了同样的问题,只是我很久没有意识到这是一个调用目标异常...... 【参考方案1】:您通过使用反射调用方法添加了额外的抽象级别。反射层将任何异常包装在 InvocationTargetException
中,这样您就可以区分由反射调用失败引起的异常实际上之间的区别(例如,您的参数列表可能无效)以及调用的方法中的故障。
只需解开 InvocationTargetException
中的原因,您就会找到原来的原因。
【讨论】:
@user550413:当然,通过打开异常并检查它。你总是可以自己扔它,如果必须的话,可以用这种方式接住它。 对于任何想知道“在InvocationTargetException
中解开原因”意味着什么的人,我刚刚发现如果您使用exception.printStackTrace()
打印它,您只需查看“导致By:" 部分而不是上半部分/正常部分。
要添加关于“展开”的解释,您还可以捕获异常并对其使用 getCause() 方法,如果需要,也可以重新抛出该异常。类似try ... catch (InvocationTargetException ex) log.error("oops!", ex.getCause())
或...catch... throw ex.getCause()
+1 @HJanrs for you just look at the "Caused By:" section instead of the top half/normal section
@DheraajBhaskar 不要像编辑自己的答案一样编辑其他人的答案,也不要对未引用的文本使用引号格式。该编辑应该已作为评论发布。【参考方案2】:
如果发生异常则抛出
InvocationTargetException - 如果底层方法抛出异常。
因此,如果使用反射 API 调用的方法抛出异常(例如运行时异常),反射 API 会将异常包装到 InvocationTargetException
中。
【讨论】:
很好的解释! 如果我期望底层方法抛出异常怎么办?我应该抓住这个异常并简单地重新抛出吗?【参考方案3】:使用InvocationTargetException
上的getCause()
方法检索原始异常。
【讨论】:
【参考方案4】:来自 Method.invoke() 的 Javadoc
Throws: InvocationTargetException - 如果底层方法抛出异常。
如果调用的方法抛出异常,则抛出此异常。
【讨论】:
所以想象一下我有一个级联的java.lang.reflect.Proxy
实例来扩充一个包装的对象。每个Proxy
都使用自己的InvocationHandler
优雅地处理特定异常(可能由包装对象抛出)。对于通过此级联直到到达正确的调用处理程序/代理的异常,在每个InvocationHandler
中,我会捕获InvocationTargetException
,打开它,检查包装的异常是否是instanceof
要处理的异常InvocationHandler
。如果不是instanceof
,我会抛出 unwrapped 异常...对吗?
我总是会抛出未包装的异常。【参考方案5】:
这将打印特定方法中的确切代码行,该方法在调用时引发异常:
try
// try code
..
m.invoke(testObject);
..
catch (InvocationTargetException e)
// Answer:
e.getCause().printStackTrace();
catch (Exception e)
// generic exception handling
e.printStackTrace();
【讨论】:
谢谢;这帮助我意识到我的问题不在于反射本身,而在于调用的方法。【参考方案6】:InvocationTargetException
可能正在结束您的ArrayIndexOutOfBoundsException
。使用反射时没有预先说明该方法会抛出什么——因此,与其使用throws Exception
方法,不如将所有异常都捕获并封装在InvocationTargetException
中。
【讨论】:
谢谢,但是我在 (AssertionError e) 和 (Exception e) 之间有什么区别?如果我总是先得到 InvocationTargetException,然后再解开原因,那么每个异常之间的区别在哪里?【参考方案7】:This 描述类似,
InvocationTargetException 是一个检查异常,它包装了一个 被调用的方法或构造函数抛出的异常。发布时 从 1.4 开始,此异常已被改进以符合通用异常链机制。 “目标异常”是 在施工时提供并通过 getTargetException() 方法现在被称为原因,并且可能是 通过 Throwable.getCause() 方法以及 前面提到的“遗留方法”。
【讨论】:
【参考方案8】:您可以像这样使用 getCause() 方法与原始异常类进行比较:
try
...
catch(Exception e)
if(e.getCause().getClass().equals(AssertionError.class))
// handle your exception 1
else
// handle the rest of the world exception
【讨论】:
【参考方案9】:在我的class
中的try
/ catch
块中调用外部class
中的记录器对象的语句出现java.lang.reflect.InvocationTargetException
错误。
单步执行 Eclipse 调试器中的代码并将鼠标悬停在记录器语句上,我看到记录器 object
是 null
(一些外部常量需要在我的 class
的最顶部实例化)。
【讨论】:
【参考方案10】:如果底层方法(使用反射调用的方法)抛出异常,则会抛出此异常。
因此,如果反射 API 调用的方法抛出异常(例如运行时异常),反射 API 会将异常包装到 InvocationTargetException 中。
【讨论】:
【参考方案11】:我也遇到了同样的问题。我使用了 e.getCause().getCause() 然后我发现这是因为我传递的参数错误。获取参数之一的值时出现 nullPointerException。 希望这会对你有所帮助。
【讨论】:
【参考方案12】:一个问题也可能是 targetSdkVersion 已提高并且您使用了已弃用的 Gradle 清单功能。再次尝试降低 targetSdkVersion 并查看它是否有效。就我而言,它是 targetSdkVersion 31 -> 30
【讨论】:
【参考方案13】:-
在 Eclipse Navigator 模式下列出所有 jar 文件
验证所有 jar 文件是否为二进制模式
【讨论】:
您如何通过在导航器中查看 jar 文件来验证它们是否处于二进制模式? @William 你让我笑了哈哈哈。这个人的回答应该被否决。【参考方案14】:我这样做后错误消失了 清理->运行 xDoclet->运行 xPackaging。
在我的工作区,在日食中。
【讨论】:
以上是关于什么可能导致 java.lang.reflect.InvocationTargetException?的主要内容,如果未能解决你的问题,请参考以下文章
引起java.lang.reflect.InvocationTargetException的一个可能原因
求救啊 webservice java.lang.reflect.InvocationTargetException
java.lang.reflect.InvocationTargetException
java.lang.reflect.InvocationTargetException - android.view.InflateException: Binary XML file line #1