根据 javadocs , InvocationTargetException.getCause()
可以为空:
Returns the cause of this exception (the thrown target exception, which may be null).
但是文档还说它包装了一个现有的异常:
InvocationTargetException is a checked exception that wraps an exception thrown by an invoked method or constructor.
所以在我看来 InvocationTargetException.getCause()
永远不会是 null
。
我错过了什么吗?
更新
是的,我错过了一些东西——InvocationTargetException
的默认构造函数会导致 getCause()
为 null。
我现在的问题是为什么要为这个类提供默认构造函数。是否存在需要以 null 原因抛出异常的用例?
最佳答案
所以。
@xtravar 对 my (much) earlier answer 的评论引起了对这个问题的另一种看法。我可能刚刚明白了。请耐心等待。
InvocationTargetException
很早就被引入到 Java 中。至少早在某些可以追溯到任何地方的 JDK 1.1.X between February 1997 to December 1998 .我怎么知道它那么旧?毕竟类上没有@since 1.1
标记。
我碰巧在 serialVersionUID
字段上看到了以下 javadoc:
/**
* Use serialVersionUID from JDK 1.1.X for interoperability
*/
没错。那又怎样?
因此,根据 Throwable.getCause()
的文档,InvocationTargetException
最终继承了:
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
类文档的以下注释结合起来:
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
(至少)。 InvocationTargetExcpetion
用于链接异常 before 异常链接被引入 Throwable
...
当 InvocationTargetException
被改造时,如前所述,我假设语言设计者想要:
- 防止
InvocationTargetException
有两个不同“原因”的可能性 - 一个存储在target
中,另一个存储在cause
中;并且仍然 - 与依赖于
target
字段的现有代码向后兼容。
这就是为什么他们将 target
字段保留为真正使用的字段并实现任何现有的构造函数,以便 cause
字段保持 null
的原因好的。 InvocationTargetException
的 getCause()
的实现,当然会返回 target
作为原因。
所以回答
Is there a usecase where the exception needs to be thrown with a null cause?
不是真的,这不是这个类是如何使用的——而且曾经是——打算使用。
然而,这个问题仍然存在:
why provide a default constructor for this class at all
(和 this constructor seems to exist ever since)
我倾向于认为这个类实际上是相当null
的。毕竟,public
构造函数允许 null
作为 Throwable 目标
。作为设计者,如果您已经允许这样做,您还可以添加 protected
默认构造函数,该构造函数将 null
显式分配给 target
,从而启用继承类根据需要构建类。
这也回答了原来的问题:
So it seems to me that InvocationTargetException.getCause() can never be null.
Am I missing something?
是的。 InvocationTargetException
确实打算有一个非null
target
和cause
。然而,这里“遗漏”的是 target
(因此 cause
)不幸的是 can 是 null
,因为没有在类里面强制它否则。
关于java - InvocationTargetException.getCause() 何时为空?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17684484/