InvocationTargetException.getCause()何时为空? [英] When is InvocationTargetException.getCause() null?

查看:328
本文介绍了InvocationTargetException.getCause()何时为空?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

按照 javadocs InvocationTargetException.getCause()可以为空:

返回此异常的原因(引发的目标异常,它可以为null).

Returns the cause of this exception (the thrown target exception, which may be null).

但是文档还说它包装了一个现有的异常:

But the documentation also says that it wraps an existing exception:

InvocationTargetException是一个已检查的异常,该异常包装了被调用的方法或构造函数引发的异常.

InvocationTargetException is a checked exception that wraps an exception thrown by an invoked method or constructor.

所以在我看来InvocationTargetException.getCause() 永远不可能是null.

So it seems to me that InvocationTargetException.getCause() can never be null.

我想念什么吗?

更新

是的,我错过了一些事情-InvocationTargetException的默认构造函数将导致getCause()为空.

Yes, I missed something -- the default constructor of InvocationTargetException would cause getCause() to be null.

我现在的问题是,为什么要为此类提供一个默认的构造函数.是否存在用例需要以空原因引发异常的用例?

The question I have now is why provide a default constructor for this class at all. Is there a usecase where the exception needs to be thrown with a null cause?

推荐答案

所以.

@xtravar对我(之前)的答案的评论已引起对这个问题的另一种看法.我可能就知道了.请忍受我.

@xtravar's comment on my (much) earlier answer has caused be to have another look at this issue. And I might just got it. Please bear with me.

InvocationTargetException最早是在Java中引入的.至少早在某些JDK 1.1.X上,它可以追溯到1997年2月之间的到1998年12月.我怎么知道这么老?毕竟,该类上没有@since 1.1标记.
我碰巧在serialVersionUID字段上看到了以下javadoc:

InvocationTargetException was introduced to Java very early. At least as early as some JDK 1.1.X which dates back to anywhere between February 1997 to December 1998. How do I know it's that old? After all, there's no @since 1.1 mark on the class.
I happened to see the following javadoc on the serialVersionUID field:

/**
 * Use serialVersionUID from JDK 1.1.X for interoperability
 */

对.那又怎样呢? 因此,根据Throwable.getCause()的文档,InvocationTargetException最终继承了该文件:

Right. So what?
So, according to docs of Throwable.getCause(), which InvocationTargetException eventually inherits:

While it is typically unnecessary to override this method, a subclass can
override it to return a cause set by some other means. This is appropriate
for a "legacy chained throwable" that predates the addition of chained
exceptions to Throwable.
...
@since 1.4

现在,请结合以下有关InvocationTargetException类文档的注释:

Now, please combine this with the following note on InvocationTargetException class docs:

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."

看看我要去哪里?
Throwable.getCause()上的注释正好针对InvocationTargetException(至少).在将Throwable ...

See where I'm getting at?
The note on Throwable.getCause() is aimed exactly at InvocationTargetException (for the least). InvocationTargetExcpetion was used to chain exceptions before exception-chaining was introduced to Throwable...

如前所述,当对InvocationTargetException进行改装时,我认为语言设计人员想要:

And when InvocationTargetException was retrofitted, as noted, I assume that the language designers wanted to:

  1. 防止InvocationTargetException具有两个不同的原因"的可能性-一个存储在target中,另一个存储在cause中;仍然
  2. 与依赖于target字段的现有代码向后兼容.
  1. prevent the possibility of InvocationTargetException having two different "causes" - one stored in target and the other in cause; and still
  2. be backward-compatible with existing code that relies on the target field.

这就是为什么他们将target字段保留为真正使用并实现任何现有构造函数的原因,以便cause字段永久保留为null的原因. InvocationTargetExceptiongetCause()实现当然会返回target作为原因.

That's why they left the target field as the one that's really used and implemented any existing constructors so that the cause field remains null for good. The implementation of getCause() for InvocationTargetException, of course, returns target as the cause.

要回答

是否存在用例需要以空原因引发异常的用例?

Is there a usecase where the exception needs to be thrown with a null cause?

不是真的,这不是类的用途-曾经是-打算使用的方式.

Not really, it's not how the class is - and was - intended to be used.

但是,这个问题仍然存在:

And yet, this question remains:

为什么要为此类提供默认的构造函数

why provide a default constructor for this class at all

(和我倾向于认为此类实际上对null相当宽容.毕竟,public构造函数允许null作为Throwable target .作为设计者,如果您已经允许这样做,则可以添加protected默认构造函数,该构造函数将null显式分配给target,从而使继承类可以构造所需的类.

I tend to think that this class is actually quite null-tolerant. After all, the public constructors permit null as the Throwable target. As a designer, if you already permitted that, you may as well add the protected default constructor that explicitly assigns null to target, enabling inheriting classes to construct the class however needed.

这也回答了原始问题:

所以在我看来,InvocationTargetException.getCause()永远无法 为空.

So it seems to me that InvocationTargetException.getCause() can never be null.

我想念什么吗?

是的.实际上,InvocationTargetException旨在具有非null targetcause.但是,这里的遗漏"是不幸的是target(因此是cause) 可以是null,因为该类中没有其他强制要求.

Yes. InvocationTargetException is indeed intended to have a non-null target and cause. However, what's "missed" here is that target (and hence cause) unfortunately can be null, as nothing in the class forces it otherwise.

这篇关于InvocationTargetException.getCause()何时为空?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆