我可以创建像
这样的例外A a = new A (new B ( new A ) );
其中A
和B
是两种不同类型的例外。
我知道Java可以做到但这样做是对的吗?
编辑:我正在编写一个Exception类型的重试,所以我正在检查Exception的getCause。当getCause为null或getCause等于我自己时,我正在断开,当getCause等于到目前为止看到的任何异常时,我是否也应该中断
答案 0 :(得分:4)
AException a = new AException(new BException(new AException));
这是合法的。
您也可以使用initCause(Throwable)
方法直接初始化原因。
如果你试图将异常作为自己的原因; e.g。
AException a = new AException();
a.initCause(a);
您将获得IllegalArgumentException("Self-causation not permitted")
。 (感谢Joachim Sauer指出这一点。)
虽然,JVM不会阻止你创建一个间接周期,但它仍然是一个非常糟糕的主意。
滥用Throwable
API。对于特殊事件直接或间接导致其自身没有逻辑意义。
可能存在假定的代码,异常的“原因”链没有任何循环。如果它遇到具有原因周期的病态异常,则这种代码很可能以令人讨厌的方式失败。
请注意,当前生成(Java 7)printStackTrace()
检测并处理“原因”周期,但前几代没有:
答案 1 :(得分: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.
答案 2 :(得分:1)
这需要三个略有不同的答案:
是,您可以将异常包装在相同类型的另一个例外中。
否,您无法在本身中包装异常(例如,在完全相同的实例中)。
不幸的是是,您可以创建一个循环(导致B的A导致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]