2012-10-03 56 views
0

我可以创建这样我们可以换用自己的一个异常在Java中

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

一个例外,AB是两个不同类型的异常。

我知道Java可以做到这一点,但这样做是正确的吗?

编辑:我正在编写异常类型的重试,所以我正在检查异常的getCause。当getCause为空或getCause等于自己时,我就中断了,当getCause等于迄今为止看到的任何异常时,我是否也应该中断

+4

我的眼睛很伤痛,看到这段代码。 –

+0

你能详细说明你试图达到的效果吗?即:给出一个你希望这样做的上下文 – Michael

+0

是否违反了任何Java约定? – Arjit

回答

4

AException一个=新AException(新BException(新AException));

这是合法的。


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

如果您尝试使异常自己的原因;例如

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

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

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

  • 这是对Throwable API的滥用。直接或间接引发特殊事件并不合乎逻辑。

  • 有可能是那里的代码认为异常的“原因”链没有任何周期。如果这个代码遇到了病因性的异常和一个原因循环,那么这种代码很可能会以一种肮脏的方式失败。

注意,目前这一代(Java 7中)printStackTrace()检测并处理了 “原因” 周期,但前几代人都没有:

+0

@JoachimSauer - 修正...谢谢... –

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. 
+0

是的,我同意但它是否违反了Java的某些规则? – Arjit

+0

@Arjit - no。查看其他答案。 –

1

那需要三个稍有不同的答案:

  1. ,您可以在相同类型的另一个例外中包装例外。

  2. 没有,你不能在本身包装异常(即在完全相同的情况下)。

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

第一个是很清楚的:你可以用一个IllegalStateException包装所造成的另一个IllegalStateExceptionIllegalArgumentException

第二个由代码防止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] 
相关问题