6

外部システムの一部のデータをリセットするために、単体テストラッパーメソッドですべてのスロー可能オブジェクトをキャッチしています。これが行われたときに元の例外を再スローしたいと思います。これを行うためにこのコードを使用しています。

if (t instanceof RuntimeException) {
    throw (RuntimeException) t;
} else if (t instanceof Error) {
    throw (Error) t;
} else {
    throw new RuntimeException(t);
}

ただし、これをすでに実行している既存のユーティリティ呼び出しはありますか?

(AssertionErrorsはエラーであるため、スローアブルをキャッチしています。)

編集:正直なところ、私は本当に例外をラップしたくないので、スローを宣言せずにスロー可能なもの(チェックされた例外を含む)をスローできるようなトリックは受け入れられます。

4

3 に答える 3

10

はい、チェックされた例外のラップを回避するメソッドを作成する方法があります。このユースケースの場合、これは完全に一致しますが、初心者を簡単に混乱させる可能性があるため、非常に注意する必要があります。ここにあります:

@SuppressWarnings("unchecked")
public static <T extends Throwable> void sneakyThrow(Throwable t) throws T {
    throw (T) t;
}

そしてあなたはそれをとして使うでしょう

catch (Throwable t) { sneakyThrow(t); }

Joachim Sauerがコメントしたように、場合によっては、行の呼び出しsneakyThrowによってメソッドが終了することをコンパイラーに納得させるのに役立ちます。宣言されたリターンタイプを変更するだけです。

@SuppressWarnings("unchecked")
public static <T extends Throwable> T sneakyThrow(Throwable t) throws T {
    throw (T) t;
}

次のように使用します。

catch (Throwable t) { throw sneakyThrow(t); }

教育目的では、バイトコードレベルで何が起こっているかを確認するのは良いことです。からの関連スニペットjavap -verbose UncheckedThrower

public static <T extends java.lang.Throwable> java.lang.RuntimeException sneakyThrow(java.lang.Throwable) throws T;
  descriptor: (Ljava/lang/Throwable;)Ljava/lang/RuntimeException;
  flags: ACC_PUBLIC, ACC_STATIC
  Code:
    stack=1, locals=1, args_size=1
       0: aload_0
       1: athrow
  Exceptions:
    throws java.lang.Throwable
  Signature: #13                          // <T:Ljava/lang/Throwable;>(Ljava/lang/Throwable;)Ljava/lang/RuntimeException;^TT;

checkcast指示がないことに注意してください。このメソッドは、合法的にthrowを宣言しTますが、これは任意の値にすることができますThrowable

于 2012-11-23T12:04:16.003 に答える
7

優れたGuavaライブラリには、Throwables.propagate(Throwable)コードが実行していることを正確に実行するメソッドがあります。JavaDoc

ドキュメントから:

RuntimeExceptionまたはErrorのインスタンスである場合は、スロー可能をそのまま伝播します。それ以外の場合は、最後の手段として、RuntimeExceptionでラップしてから伝播します。

于 2012-11-23T12:12:50.777 に答える
0

おそらくsetDefaultUncaughtExceptionHandler(Thread.UncaughtExceptionHandler)あなたを助けることができます。そこで、発生するすべての例外に対してグローバル例外ハンドラーを定義できます。

于 2012-11-23T12:01:30.273 に答える