0

我可以创建一个异常吗

A a = new A (new B ( new A ) );

whereAB是两种不同类型的异常。

我知道 Java 可以做到,但这样做是否正确?

编辑:我正在写一个异常类型的重试,所以我正在检查异常的getCause。当 getCause 为 null 或 getCause 本身相等时我会中断,当 getCause 等于迄今为止看到的任何异常时我是否也应该中断

4

3 回答 3

4

AException a = new AException (new BException (new AException) );

这是合法的。


您也可以直接使用该initCause(Throwable)方法初始化原因。

如果您试图将异常作为自己的原因;例如

 AException a = new AException();
 a.initCause(a);

你会得到一个IllegalArgumentException("Self-causation not permitted"). (感谢 Joachim Sauer 指出这一点。)

虽然 JVM 不会阻止您创建间接循环,但它仍然是一个非常糟糕的主意

  • 这是对ThrowableAPI 的滥用。一个异常事件直接或间接地引起自己是没有逻辑意义的。

  • 那里可能有代码假设异常的“原因”链没有任何循环。如果遇到具有原因循环的病态异常,此类代码可能会以令人讨厌的方式失败。

请注意,当前一代(Java 7)printStackTrace()检测并处理“原因”循环,但前几代没有:

于 2012-10-03T05:17:44.047 回答
1

考虑您有以下课程。

public static class A extends Exception {
    public A() {}
    public A(Exception e) {}

}
public static class B extends Exception {
    public B(Exception e) {}
    public B() {}
}

现在,如果您看到当您出现在默认构造函数中时,包装异常总是结束。在那之前你应该打电话getCause()

 throw new B(new A(new B()));//Ends with B since no exception is wrapped inside it.
于 2012-10-03T04:39:20.373 回答
1

这需要三个略有不同的答案:

  1. 的,您可以将一个异常包装在另一个相同类型的异常中。

  2. ,您不能将异常本身包装起来(即在完全相同的实例中)。

  3. 不幸的,您可以创建一个循环(A 导致 B 导致 A 导致 B ...)。

第一个非常清楚:您可以包装由另一个引起的IllegalStateException包装。IllegalArgumentExceptionIllegalStateException

第二个被里面的代码阻止initClause()(由构造函数调用,或者如果之前从未调用过,可以直接调用),防止自因果(确实cause == this用作没有设置原因的标志,以区分它从这cause == null意味着原因被明确设置为null)。

第三点不好,但在实践中不应该经常发生,因为你必须做一些额外的工作才能得到它:

Exception e1 = new Exception();
Exception e2 = new Exception(e1);
e1.initCause(e2);

幸运的是printStackTrace(),实际上处理了这种情况:

java.lang.Exception: java.lang.Exception
    at ScratchMain.main(ScratchMain.java:6)
Caused by: java.lang.Exception
    at ScratchMain.main(ScratchMain.java:5)
    [CIRCULAR REFERENCE:java.lang.Exception: java.lang.Exception]
于 2012-10-03T05:25:05.023 回答