0

次のような例外を作成できますか

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

ここでA、とBは2つの異なるタイプの例外です。

私は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

それには、わずかに異なる 3 つの答えが必要です。

  1. はい、例外を同じタイプの別の例外にラップできます。

  2. いいえ、例外をそれ自体に(つまり、まったく同じインスタンスに)ラップすることはできません。

  3. 残念ながら、はい、ループを作成できます(AがBを引き起こし、AがBを引き起こします...)。

最初のものは非常に明確です。別の によって引き起こされたIllegalStateExceptionラッピングをラップできます。IllegalArgumentExceptionIllegalStateException

initClause()2番目のものは、自己因果関係を防ぐコード(コンストラクターによって呼び出されるか、以前に呼び出されたことがない場合は直接呼び出すことができます)によって防止されます(実際cause == this、原因が設定されていないフラグとして使用され、それを区別しますcause == nullこれは、原因が明示的に に設定されたことを意味します) null

3 番目のビットは悪いですが、それを取得するには追加の作業を行う必要があるため、実際にはあまり頻繁に発生するべきではありません。

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 に答える
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 に答える