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

发布于 2024-11-07 17:30:05 字数 682 浏览 6 评论 0原文

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

我的代码中有这样的地方:

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

事情是这样的,当它尝试调用某些方法时,它会抛出异常 IncationTargetException 而不是其他一些预期的异常(特别是 ArrayIndexOutOfBoundsException)。 因为我实际上知道调用了什么方法,所以我直接转到该方法代码,并为应该抛出 ArrayIndexOutOfBoundsException 的行添加了一个 try-catch 块,它确实抛出了 ArrayIndexOutOfBoundsException ,如下所示预期的。然而当它上升时 以某种方式更改为 InitationTargetException 以及上面的代码 catch(Exception e) e 是 InitationTargetException 而不是 ArrayIndexOutOfBoundsException 正如预期的那样。

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

Well, I've tried to understand and read what could cause it but I just can't get it:

I have this somewhere in my code:

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

Thing is that, when it tries to invoke some method it throws
InvocationTargetException instead of some other expected exception (specifically ArrayIndexOutOfBoundsException).
As I actually know what method is invoked I went straight to this method code and added a try-catch block for the line that suppose to throw ArrayIndexOutOfBoundsException and it really threw ArrayIndexOutOfBoundsException as expected. Yet when going up it
somehow changes to InvocationTargetException and in the code above catch(Exception e)
e is InvocationTargetException and not ArrayIndexOutOfBoundsException
as expected.

What could cause such a behavior or how can I check such a thing?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(16

束缚m 2024-11-14 17:30:05

您通过反射调用该方法添加了额外的抽象级别。反射层将任何异常包装在 InitationTargetException 中,它可以让您区分实际上由反射调用失败引起的异常(也许您的参数列表不是例如,有效)并且调用的方法内失败。

只需解开 InitationTargetException 中的原因,您就会找到原始的原因。

为此,您可以执行 exception.printStackTrace() 并查看“Caused By:”部分而不是上半部分/正常部分。

您还可以捕获异常并对其使用 getCause() 方法,如果需要,也可以重新抛出该异常。类似于 try {...} catch (InitationTargetException ex) { log.error("oops!", ex.getCause()) }...catch... { throw ex.getCause() }

You've added an extra level of abstraction by calling the method with reflection. The reflection layer wraps any exception in an InvocationTargetException, which lets you tell the difference between an exception actually caused by a failure in the reflection call (maybe your argument list wasn't valid, for example) and a failure within the method called.

Just unwrap the cause within the InvocationTargetException and you'll get to the original one.

To do that, you can do exception.printStackTrace() and look at the "Caused By:" section instead of the top half/normal section.

You can also catch the exception and use the getCause() method on it, which can also be re-thrown, if desired. Something like try {...} catch (InvocationTargetException ex) { log.error("oops!", ex.getCause()) } or ...catch... { throw ex.getCause() }

橪书 2024-11-14 17:30:05

如果出现以下情况,则抛出异常

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

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

The exception is thrown if

InvocationTargetException - if the underlying method throws an exception.

So if the method, that has been invoked with reflection API, throws an exception (runtime exception for example), the reflection API will wrap the exception into an InvocationTargetException.

苍风燃霜 2024-11-14 17:30:05

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

Use the getCause() method on the InvocationTargetException to retrieve the original exception.

如果没有 2024-11-14 17:30:05

来自 Method.invoke() 的 Javadoc

抛出:InitationTargetException - 如果基础方法抛出异常。

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

From the Javadoc of Method.invoke()

Throws: InvocationTargetException - if the underlying method throws an exception.

This exception is thrown if the method called threw an exception.

一场春暖 2024-11-14 17:30:05

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

try {

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

} catch (InvocationTargetException e) {

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

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

This will print the exact line of code in the specific method, which when invoked, raised the exception:

try {

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

} catch (InvocationTargetException e) {

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

    // generic exception handling
    e.printStackTrace();
}
水晶透心 2024-11-14 17:30:05

InitationTargetException 可能正在包装您的 ArrayIndexOutOfBoundsException。使用反射时,事先无法得知该方法可能会抛出什么异常 - 因此,所有异常都被捕获并包装在 InitationTargetException 中,而不是使用 抛出异常 方法。

That InvocationTargetException is probably wrapping up your ArrayIndexOutOfBoundsException. There is no telling upfront when using reflection what that method can throw -- so rather than using a throws Exception approach, all the exceptions are being caught and wrapped up in InvocationTargetException.

英雄似剑 2024-11-14 17:30:05

描述了类似的内容,

InspirationTargetException 是一个检查异常,它包装了
调用的方法或构造函数引发的异常。截至发布时
1.4 中,该异常已被改进以符合通用异常链机制。 “目标异常”是
在施工时提供并通过
getTargetException() 方法现在已知为原因,并且可能是
通过 Throwable.getCause() 方法以及
前面提到的“传统方法”。

This describes something like,

InvocationTargetException is a checked exception that wraps an
exception thrown by an invoked method or constructor. As of release
1.4, this exception has been retrofitted to conform to the general purpose exception-chaining mechanism. The "target exception" that is
provided at construction time and accessed via the
getTargetException() method is now known as the cause, and may be
accessed via the Throwable.getCause() method, as well as the
aforementioned "legacy method."

初心 2024-11-14 17:30:05

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

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

You can compare with the original exception Class using getCause() method like this :

try{
  ...
} catch(Exception e){
   if(e.getCause().getClass().equals(AssertionError.class)){
      // handle your exception  1
   } else {
      // handle the rest of the world exception 
   }
} 
深海里的那抹蓝 2024-11-14 17:30:05

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

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

I had a java.lang.reflect.InvocationTargetException error from a statement calling a logger object in an external class inside a try / catch block in my class.

Stepping through the code in the Eclipse debugger & hovering the mouse over the logger statement I saw the logger object was null (some external constants needed to be instantiated at the very top of my class).

卸妝后依然美 2024-11-14 17:30:05

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

A problem can also be that the targetSdkVersion is upped and that you use deprecated Gradle manifest features. Try lowering the targetSdkVersion again and see if it works. In my case it was targetSdkVersion 31 -> 30

梦幻的心爱 2024-11-14 17:30:05

调用目标异常

我坚信任何命名约定都需要付出勤奋的思考
在其中。而且,我们的问题很可能有其自身的意义
如果我们尝试寻找名称背后的基本原理,答案就在名称中。

让我们把这个名字分成三部分。
调用”“目标”方法时发生“异常”。
并且,当在 Java 中通过反射调用方法时,此包装器会引发异常。执行该方法时,可能会引发任何类型的异常。根据设计,异常的实际原因被抽象出来,让最终用户知道异常是在基于反射的方法访问期间发生的。为了获取实际原因,建议捕获异常并调用 ex.getCause()。最佳实践是,事实上,从捕获 InvocableTargetException 的 catch 块中抛出原因,

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

我知道它与其他答案类似,但我想更清楚地了解“何时”此异常类型是由Java生成的,所以它对任何人来说都不神秘。

Invocation Target Exception:

I strongly believe that any naming convention has diligent thoughts invested
in it. And, it is more than likely that our questions have their
answers in the names, if we tried finding a rationale behind the name.

Let's break the name up into 3 parts.
"Exception" has occurred when "Invoking" a "Target" method.
And, the exception is thrown with this wrapper when, a method is invoked via reflection in Java. While executing the method, there could be any type of exception raised. It is by design, that the actual cause of the exception is abstracted away, to let the end user know that the exception was one that occurred during a reflection based method access. In order to get the actual cause, it is recommended that the exception is caught and ex.getCause() is called. Best practice is to, in fact throw the cause from the catch block that caught the InvocationTargetException

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

I know it is similar to the other answers, but I wanted to make it more clear about "when" this exception type is generated by Java, so that it is a mystery to none.

凉墨 2024-11-14 17:30:05

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

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

This exception is thrown if the underlying method(method called using Reflection) throws an exception.

So if the method, that has been invoked by reflection API, throws an exception (as for example runtime exception), the reflection API will wrap the exception into an InvocationTargetException.

无人问我粥可暖 2024-11-14 17:30:05

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

I was facing the same problem. I used e.getCause().getCause() then I found that it was because of wrong parameters I was passing. There was nullPointerException in fetching the value of one of the parameters.
Hope this will help you.

慢慢从新开始 2024-11-14 17:30:05

对于 Android 开发者:
我正在运行 adb shell input tap x y,然后我将其更改为仅输入 tap input tap x y 它工作得很好。

说明:adb 是您在计算机上使用的工具,“adb shell”在设备(或模拟器)上打开一个 shell,“adb shell 命令”在其上运行命令。
因此,如果您想在设备上以编程方式运行命令,只需删除“adb shell”:

In case of android developers:
I was running adb shell input tap x y, then I changed it to input tap only input tap x y it worked perfectly.

Description: adb is a tool you use on your computer, "adb shell" opens a shell on the device (or emulator), and "adb shell command" runs the command on it.
So if you want to run the command programmatically on the device, just remove "adb shell":

画▽骨i 2024-11-14 17:30:05
  1. 从 Eclipse Navigator 模式列出所有 jar 文件
  2. 验证所有 jar 文件是否处于二进制模式
  1. List all jar files from the Eclipse Navigator mode
  2. Verify that all the jar files are in binary mode
酸甜透明夹心 2024-11-14 17:30:05

我这样做后错误消失了
清理 -> 运行 xDoclet -> 运行 xPackaging。

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

The error vanished after I did
Clean->Run xDoclet->Run xPackaging.

In my workspace, in ecllipse.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文