我可以创建一个异常吗
A a = new A (new B ( new A ) );
whereA
和B
是两种不同类型的异常。
我知道 Java 可以做到,但这样做是否正确?
编辑:我正在写一个异常类型的重试,所以我正在检查异常的getCause。当 getCause 为 null 或 getCause 本身相等时我会中断,当 getCause 等于迄今为止看到的任何异常时我是否也应该中断
我可以创建一个异常吗
A a = new A (new B ( new A ) );
whereA
和B
是两种不同类型的异常。
我知道 Java 可以做到,但这样做是否正确?
编辑:我正在写一个异常类型的重试,所以我正在检查异常的getCause。当 getCause 为 null 或 getCause 本身相等时我会中断,当 getCause 等于迄今为止看到的任何异常时我是否也应该中断
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 不会阻止您创建间接循环,但它仍然是一个非常糟糕的主意。
这是对Throwable
API 的滥用。一个异常事件直接或间接地引起自己是没有逻辑意义的。
那里可能有代码假设异常的“原因”链没有任何循环。如果遇到具有原因循环的病态异常,此类代码可能会以令人讨厌的方式失败。
请注意,当前一代(Java 7)printStackTrace()
检测并处理“原因”循环,但前几代没有:
考虑您有以下课程。
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.
这需要三个略有不同的答案:
是的,您可以将一个异常包装在另一个相同类型的异常中。
不,您不能将异常本身包装起来(即在完全相同的实例中)。
不幸的是,您可以创建一个循环(A 导致 B 导致 A 导致 B ...)。
第一个非常清楚:您可以包装由另一个引起的IllegalStateException
包装。IllegalArgumentException
IllegalStateException
第二个被里面的代码阻止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]