java - InvocationTargetException.getCause() 何时为空?

标签 java invocationtargetexception

根据 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 被改造时,如前所述,我假设语言设计者想要:

  1. 防止 InvocationTargetException 有两个不同“原因”的可能性 - 一个存储在 target 中,另一个存储在 cause 中;并且仍然
  2. 与依赖于 target 字段的现有代码向后兼容。

这就是为什么他们将 target 字段保留为真正使用的字段并实现任何现有的构造函数,以便 cause 字段保持 null 的原因好的。 InvocationTargetExceptiongetCause() 的实现,当然会返回 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 targetcause。然而,这里“遗漏”的是 target(因此 cause)不幸的是 cannull,因为没有在类里面强制它否则。

关于java - InvocationTargetException.getCause() 何时为空?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17684484/

相关文章:

java - Jackson 序列化动态类型对象

java - 如何将安装在移动设备上的 J2me Midlet 连接到 Java 应用程序?

java - 如何从字符串变量中的转义序列中转义

java.lang.reflect.InitationTargetException

尝试创建 Button 时抛出 JavaFX InitationTargetException

java - 如何解决for循环中的InvocableTargetException? (寻找整个堆栈跟踪)

java - 在 http API 中引发 "bad requests"异常是否是一种好习惯 - 与(Java)最佳实践相矛盾

java - 多项式加 : Unable to run code

java - 小程序错误 - java.lang.reflect.InitationTargetException

Java `InvocationTargetException` 通过反射进行类实例化