什么可能导致 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 调试器中的代码并将鼠标悬停在记录器语句上,我看到记录器 objectnull(一些外部常量需要在我的 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

java.lang.reflect.Constructor

java.lang.reflect.Method