所以。
@xtravar 对我(很多)较早的答案的评论导致重新审视这个问题。我可能刚刚得到它。请多多包涵。
InvocationTargetException
很早就被引入Java。至少可以追溯到1997 年 2 月到 1998 年 12 月之间的任何 JDK 1.1.X。我怎么知道它这么旧?毕竟,@since 1.1
课堂上没有分数。
我碰巧在serialVersionUID
现场看到以下 javadoc:
/**
* Use serialVersionUID from JDK 1.1.X for interoperability
*/
正确的。所以呢?
因此,根据 docs of 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
用于链接异常Throwable
如前所述,当InvocationTargetException
进行改造时,我假设语言设计者想要:
- 防止出现
InvocationTargetException
两种不同“原因”的可能性 - 一个存储在 中target
,另一个存储在 中cause
;还是
- 与依赖该
target
字段的现有代码向后兼容。
这就是为什么他们将这个target
领域作为真正使用并实现了任何现有构造函数的领域,以便该cause
领域永远存在null
。当然,getCause()
for的实现作为原因返回。InvocationTargetException
target
所以来回答
是否存在需要以空原因引发异常的用例?
并非如此,这不是该类的用途——而且是——打算使用的方式。
然而,这个问题仍然存在:
为什么要为这个类提供一个默认构造函数
(并且这个构造函数似乎从那以后就存在了)
我倾向于认为这个类实际上是相当null
宽容的。毕竟,public
构造函数允许null
作为Throwable target
. 作为设计者,如果您已经允许这样做,您也可以添加显式分配给的protected
默认构造函数,从而使继承类能够根据需要构造类。null
target
这也回答了原来的问题:
所以在我看来 InvocationTargetException.getCause() 永远不能为空。
我错过了什么吗?
是的。InvocationTargetException
确实打算有一个非null
target
和cause
。然而,这里“遗漏”的是target
(因此cause
)不幸的是可以是null
,因为课堂上没有任何东西强迫它。