我们可以用java包装一个异常吗

我们可以用java包装一个异常吗,java,exception,exception-handling,Java,Exception,Exception Handling,我可以创建一个异常吗 A a = new A (new B ( new A ) ); 其中A和B是两种不同类型的异常 我知道Java可以做到,但这样做对吗 编辑:我正在写一个关于异常类型的重试,所以我正在检查异常的原因。当getCause为null或getCause等于自身时,我将中断,当getCause等于迄今为止看到的任何异常时,我是否也应中断考虑您有以下类 public static class A extends Exception { public A() {} pu

我可以创建一个异常吗

A a = new A (new B ( new A ) );
其中
A
B
是两种不同类型的异常

我知道Java可以做到,但这样做对吗


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

考虑您有以下类

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()


假设你有以下课程

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()

AEException a=新AEException(新AEException(新AEException))

这是合法的


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

如果你试图使例外成为它自己的原因;e、 g

 AException a = new AException();
 a.initCause(a);
您将得到一个
IllegalArgumentException(“不允许自我因果关系”)
。(感谢约阿希姆·绍尔指出这一点。)

尽管JVM不会阻止您创建一个间接循环,但这确实是一个坏主意

  • 这是对可丢弃的
    API的滥用。一个异常事件直接或间接导致其自身的发生在逻辑上是没有意义的

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

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

AEException a=新AEException(新AEException(新AEException))

这是合法的


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

如果你试图使例外成为它自己的原因;e、 g

 AException a = new AException();
 a.initCause(a);
您将得到一个
IllegalArgumentException(“不允许自我因果关系”)
。(感谢约阿希姆·绍尔指出这一点。)

尽管JVM不会阻止您创建一个间接循环,但这确实是一个坏主意

  • 这是对可丢弃的
    API的滥用。一个异常事件直接或间接导致其自身的发生在逻辑上是没有意义的

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

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


    • 这需要三个稍微不同的答案:

    • ,您可以将一个异常包装到另一个相同类型的异常中

    • ,不能将异常包装在自身中(即在完全相同的实例中)

    • 不幸的是,,您可以创建一个循环(a导致B导致a导致B…)

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

      第二个是由
      initClause()
      中的代码阻止的(该代码由构造函数调用,或者如果以前从未调用过它,则可以直接调用),这防止了自因果关系(事实上,
      cause==此
      用作未设置原因的标志,以区别于
      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]
      

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

    • ,您可以将一个异常包装到另一个相同类型的异常中

    • ,不能将异常包装在自身中(即在完全相同的实例中)

    • 不幸的是,,您可以创建一个循环(a导致B导致a导致B…)

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

      第二个是由
      initClause()
      中的代码阻止的(该代码由构造函数调用,或者如果以前从未调用过它,则可以直接调用),这防止了自因果关系(事实上,
      cause==此
      用作未设置原因的标志,以区别于
      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]
      

      看到那段代码我的眼睛很痛。你能详细说明一下你想要达到的效果吗?例如:给出一个你想这样做的上下文,它是否打破了任何Java约定?我正在写一个关于异常类型的重试,所以我正在检查异常的getCause。当getCause为null或getCause本身相等时,我正在中断,我是否也应该中断当getCause等于迄今为止看到的任何异常时?为什么要使用
      MyException e=new MyException
      创建异常?只需
      抛出new MyException(…)
      。此外,为什么需要
      异常