ChatGPT解决这个技术问题 Extra ChatGPT

什么可能导致 java.lang.reflect.InvocationTargetException?

好吧,我试图理解和阅读可能导致它的原因,但我就是无法理解:

我的代码中有这个:

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

事情是,当它尝试调用某个方法时,它会抛出 InvocationTargetException 而不是其他一些预期的异常(特别是 ArrayIndexOutOfBoundsException)。因为我实际上知道调用了什么方法,所以我直接进入了这个方法代码,并为假设抛出 ArrayIndexOutOfBoundsException 的行添加了一个 try-catch 块,它确实按预期抛出了 ArrayIndexOutOfBoundsException。然而,当上升时,它以某种方式更改为 InvocationTargetException 并且在上面的代码中 catch(Exception e) e 是 InvocationTargetException 而不是 ArrayIndexOutOfBoundsException 符合预期。

什么可能导致这种行为或者我该如何检查这种事情?

我遇到了同样的问题,只是我有一段时间没有意识到这是一个调用目标异常......

u
user207421

您通过使用反射调用方法添加了额外的抽象级别。反射层将任何异常包装在 InvocationTargetException 中,这样您就可以区分由反射调用失败导致的异常实际上(例如,您的参数列表可能无效)以及调用的方法中的故障。

只需解开 InvocationTargetException 中的原因,您就可以找到原始原因。


user550413:当然,通过打开异常并检查它。你总是可以自己扔它,如果必须的话,可以用这种方式接住它。
对于任何想知道“在 InvocationTargetException 中解开原因”意味着什么的人,我刚刚发现如果您使用 exception.printStackTrace() 打印它,您只需查看“原因:”部分而不是顶部半/正常部分。
要添加关于“展开”的解释,您还可以捕获异常并对其使用 getCause() 方法,如果需要,也可以重新抛出该异常。 try {...} catch (InvocationTargetException ex) { log.error("oops!", ex.getCause()) }...catch... { throw ex.getCause() } 之类的东西
you just look at the "Caused By:" section instead of the top half/normal section +1 @HJanrs
@DheraajBhaskar 不要像编辑自己的答案一样编辑其他人的答案,也不要对未引用的文本使用引号格式。该编辑应该已作为评论发布。
A
Andreas Dolk

抛出异常,如果

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

因此,如果使用反射 API 调用的方法抛出异常(例如运行时异常),反射 API 会将异常包装到 InvocationTargetException 中。


很好的解释!
如果我期望底层方法抛出异常怎么办?我应该抓住这个异常并简单地重新抛出吗?
S
Sumit Singh

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


g
gEdringer

来自 Method.invoke() 的 Javadoc

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

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


所以想象一下我有一个级联的 java.lang.reflect.Proxy 实例来扩充一个包装的对象。每个 Proxy 都使用自己的 InvocationHandler 优雅地处理特定异常(可能由包装对象引发)。对于通过此级联直到到达正确的调用处理程序/代理的异常,在每个 InvocationHandler 中,我将捕获 InvocationTargetException,打开它,检查包装的异常是否是 instanceof 要由它处理的异常InvocationHandler。如果它不是 instanceof,我会抛出 unwrapped 异常...对吗?
我总是会抛出未包装的异常。
R
ROMANIA_engineer

这将打印特定方法中的确切代码行,调用该方法时引发异常:

try {

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

} catch (InvocationTargetException e) {

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

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

谢谢;这帮助我意识到我的问题不在于反射本身,而在于调用的方法。
L
Liv

那个 InvocationTargetException 可能正在结束您的 ArrayIndexOutOfBoundsException。使用反射时没有预先说明该方法会抛出什么 - 因此,与其使用 throws Exception 方法,所有异常都被捕获并包含在 InvocationTargetException 中。


谢谢,但是例如, (AssertionError e) 和 (Exception e) 我将如何区分?如果我总是先得到 InvocationTargetException,然后再解开原因,每个异常之间会有什么不同?
M
Mind Peace

This 描述类似,

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


M
Mehdi

您可以使用 getCause() 方法与原始异常类进行比较,如下所示:

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

S
Stuart Cardall

我的 class 中的 try / catch 块内的外部 class 中调用记录器对象的语句出现 java.lang.reflect.InvocationTargetException 错误。

单步执行 Eclipse 调试器中的代码 &将鼠标悬停在记录器语句上,我看到记录器 objectnull(需要在 class 的最顶部实例化一些外部常量)。


j
jobbert

一个问题也可能是 targetSdkVersion 已提高并且您使用了已弃用的 Gradle 清单功能。再次尝试降低 targetSdkVersion 并查看它是否有效。就我而言,它是 targetSdkVersion 31 -> 30


N
Nikhil Kumar

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

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


D
Deepak Vajpayee

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


A
Abhay Nagaraj

调用目标异常:

我坚信任何命名约定都投入了勤奋的思想。而且,如果我们试图找到名称背后的理由,我们的问题很可能在名称中得到了答案。

让我们将名称分为 3 个部分。当“Invoking”一个“Target”方法时发生了“Exception”。并且,当通过 Java 中的 reflection 调用方法时,此包装器会引发异常。在执行该方法时,可能会引发任何类型的异常。通过设计,异常的实际原因被抽象出来,让最终用户知道异常是在基于反射的方法访问期间发生的异常。为了得到实际原因,建议捕获异常并调用ex.getCause()。最佳实践实际上是从捕获 InvocationTargetException 的 catch 块中抛出原因

try{
    method.invoke();
} catch(InvocationTargetException ite) {
    throw ite.getCause();
} catch(Exception e) {
    // handle non-reflection originated exceptions
    throw e;
}

我知道它与其他答案相似,但我想更清楚地说明“何时”这种异常类型是由 Java 生成的,所以这对任何人来说都是一个谜。


j
j0k

列出 Eclipse Navigator 模式下的所有 jar 文件 验证所有 jar 文件是否处于二进制模式


您如何通过在导航器中查看 jar 文件来验证它们是否处于二进制模式?
@William 你让我笑了哈哈哈。这个人的回答应该被否决。
A
Ashutosh Anand

在我执行 Clean->Run xDoclet->Run xPackaging 后,错误消失了。

在我的工作区,在日食中。