什么可能导致 java.lang.reflect.InitationTargetException?
好吧,我试图理解并阅读可能导致它的原因,但我就是无法理解:
我的代码中有这样的地方:
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 throwsInvocationTargetException
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 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(16)
您通过反射调用该方法添加了额外的抽象级别。反射层将任何异常包装在
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() }
如果出现以下情况,则抛出异常
因此,如果使用反射 API 调用的方法抛出异常(例如运行时异常),反射 API 会将异常包装到
InitationTargetException
中。The exception is thrown if
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
.使用
InitationTargetException
上的getCause()
方法来检索原始异常。Use the
getCause()
method on theInvocationTargetException
to retrieve the original exception.来自 Method.invoke() 的 Javadoc
如果调用的方法抛出异常,则抛出此异常。
From the Javadoc of Method.invoke()
This exception is thrown if the method called threw an exception.
这将打印特定方法中的确切代码行,该方法在调用时引发异常:
This will print the exact line of code in the specific method, which when invoked, raised the exception:
该
InitationTargetException
可能正在包装您的ArrayIndexOutOfBoundsException
。使用反射时,事先无法得知该方法可能会抛出什么异常 - 因此,所有异常都被捕获并包装在InitationTargetException
中,而不是使用抛出异常
方法。That
InvocationTargetException
is probably wrapping up yourArrayIndexOutOfBoundsException
. There is no telling upfront when using reflection what that method can throw -- so rather than using athrows Exception
approach, all the exceptions are being caught and wrapped up inInvocationTargetException
.这描述了类似的内容,
This describes something like,
您可以使用 getCause() 方法与原始异常类进行比较,如下所示:
You can compare with the original exception Class using getCause() method like this :
我在
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 externalclass
inside atry
/catch
block in myclass
.Stepping through the code in the Eclipse debugger & hovering the mouse over the logger statement I saw the logger
object
wasnull
(some external constants needed to be instantiated at the very top of myclass
).问题还可能是 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
调用目标异常:
让我们把这个名字分成三部分。
“调用”“目标”方法时发生“异常”。
并且,当在 Java 中通过反射调用方法时,此包装器会引发异常。执行该方法时,可能会引发任何类型的异常。根据设计,异常的实际原因被抽象出来,让最终用户知道异常是在基于反射的方法访问期间发生的。为了获取实际原因,建议捕获异常并调用
ex.getCause()
。最佳实践是,事实上,从捕获 InvocableTargetException 的 catch 块中抛出原因,我知道它与其他答案类似,但我想更清楚地了解“何时”此异常类型是由Java生成的,所以它对任何人来说都不神秘。
Invocation Target Exception:
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 theInvocationTargetException
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.
如果底层方法(使用反射调用的方法)抛出异常,则会抛出此异常。
因此,如果反射 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.
我面临着同样的问题。我使用了 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.
对于 Android 开发者:
我正在运行
adb shell input tap x y
,然后我将其更改为仅输入 tapinput 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 onlyinput 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":
我这样做后错误消失了
清理 -> 运行 xDoclet -> 运行 xPackaging。
在我的工作区,在日蚀中。
The error vanished after I did
Clean->Run xDoclet->Run xPackaging.
In my workspace, in ecllipse.