web-dev-qa-db-ja.com

例外のタイプとネストされた例外のタイプの両方をどのようにチェックしますか?

タイプAppExceptionの例外をキャッチしたが、タイプStreamExceptionのネストされた例外がある場合にのみ、その例外に対して特定のアクションを実行したいとします。

if (e instanceof AppException)
{
    // only handle exception if it contains a
    // nested exception of type 'StreamException'

ネストされたStreamExceptionを確認するにはどうすればよいですか?

19
Timothy

実行:if (e instanceof AppException and e.getCause() instanceof StreamException)

21
Marcelo

原因を調べる代わりに、特定の目的のためにAppExceptionをサブクラス化してみることができます。

例えば。

class StreamException extends AppException {}

try {
    throw new StreamException();
} catch (StreamException e) {
   // treat specifically
} catch (AppException e) {
   // treat generically
   // This will not catch StreamException as it has already been handled 
   // by the previous catch statement.
}

Javaでもこのパターンを見つけることができます。1つは例 IOException です。これは、EOFExceptionを含むがこれに限定されない、さまざまなタイプのIOExceptionのスーパークラスです。 、FileNotFoundException、およびUnknownHostException。

5
Dunes
if (e instanceof AppException) {
    boolean causedByStreamException = false;
    Exception currExp = e;
    while (currExp.getCause() != null){
        currExp = currExp.getCause();
        if (currExp instanceof StreamException){
            causedByStreamException = true;
            break;
        }
    }
    if (causedByStreamException){
       // Write your code here
    }
}
1

ApacheのExceptionUtils(org.Apache.commons.lang3.exception.ExceptionUtils)は、例外の検査と処理のためのユーティリティの本当に素晴らしいコレクションです。使用できるメソッドhasCauseが含まれています。

if (e instanceof AppException && ExceptionUtils.hasCause(ex, StreamException.class)) {
  ...
}

このメソッドの良い点は、原因が直接の原因だけでなく、例外スタックトレースのどこかにあるかどうかを調べるためにドリルダウンすることです。

hasCauseは渡された例外もチェックすることに注意してください。例外自体がタイプであるか、チェーン内のラップされた例外がそのタイプであるかを確認したい場合は、1回の呼び出しのみが必要です。

0
crowmagnumb