什么时候InvocationTargetException.getCause()null?

时间:2013-07-16 18:40:38

标签: java invocationtargetexception

根据javadocsInvocationTargetException.getCause()可以为null:

  

返回此异常的原因(抛出的目标异常,可能为null)。

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

  

InvocationTargetException是一个经过检查的异常,它包装了被调用的方法或构造函数抛出的异常。

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

我错过了什么吗?

更新

是的,我错过了一些东西 - InvocationTargetException的默认构造函数会导致getCause()为空。

我现在的问题是为什么要提供这个类的默认构造函数。是否存在需要使用null原因抛出异常的用例?

4 个答案:

答案 0 :(得分:1)

InvocationTargetException扩展了ReflectiveOperationException状态

  

反射操作抛出的异常超常类异常   核心反思。

使用反射调用方法(或构造函数)时。

Method method = ...
method.invoke(instance, ...);

如果该方法引发异常,它将存储在target的{​​{1}}字段中。在大多数反思案例中都会发生这种情况。

有一个空构造函数的事实让我相信它可能在其他情况下使用不同。

JDK 7

InvocationTargetException

答案 1 :(得分:1)

所以

@ 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用于在引入异常链之前将异常链接到Throwable ...

InvocationTargetException被改装时,如上所述,我认为语言设计师想要:

  1. 防止InvocationTargetException出现两种不同的原因" - 一个存储在target中,另一个存储在cause中;仍然
  2. 向后兼容依赖于target字段的现有代码。
  3. 这就是为什么他们离开target字段作为真正使用的字段并实现了任何现有的构造函数,以便cause字段保持null为好。当然,getCause() InvocationTargetException的实施会以target为原因。

    所以回答

      

    是否存在需要以null原因抛出异常的用例?

    不是真的,这不是课程的方式 - 并且 - 意图被使用。

    然而,这个问题仍然存在:

      

    为什么要为所有

    提供此类的默认构造函数

    (和this constructor seems to exist ever since

    我倾向于认为这个班级实际上非常null - 宽容。毕竟,public构造函数允许null作为Throwable target 。作为设计人员,如果您已经允许,那么您也可以添加protected默认构造函数,将null显式指定给target,从而启用继承类来构造所需的类。

    这也回答了原来的问题:

      

    所以在我看来,InvocationTargetException.getCause()永远不会   是空的。

         

    我错过了什么吗?

    是。 InvocationTargetException确实意图拥有非null targetcause。但是,错过了什么"这是target(因此cause),不幸的是可以成为null,因为班级中的任何内容都不会强制它。

答案 2 :(得分:0)

我同意你的观点 - 我不知道InvocationTargetException如何可以为null,因为它只在目标抛出异常时抛出。

我的猜测是getCause()的文本指出“可能为null”只是从Throwable.getCause()Javadoc复制的样板文件。

答案 3 :(得分:0)

首先,值得一提的是,null构造函数不仅允许protected原因。您还可以调用价值为public的{​​{1}}的{​​{1}}构造函数。不会发生target ......

话虽如此, 看起来不仅仅是设计师刚下滑的东西。

可能是设计人员希望通过反射实现类的实例化,如:

null

这样,util方法可以创建NullPointerException个实例并将它们传递给客户端代码,从而累计特定原因。