web-dev-qa-db-ja.com

Javaでは、同じcatchブロックで2つの例外をキャッチできますか?

同じ処理ロジックが必要なため、2つの例外をキャッチする必要があります。私は次のようなことをしたいです:

catch (Exception e, ExtendsRuntimeException re) {
    // common logic to handle both exceptions
}

各catchブロックでハンドラーコードの重複を避けることは可能ですか?

107
user710818

Java 7以降

Multiple-exception catches は、Java 7以降でサポートされています。

構文は次のとおりです。

try {
     // stuff
} catch (Exception1 | Exception2 ex) {
     // Handle both exceptions
}

exの静的タイプは、リストされている例外の最も特殊な共通スーパータイプです。キャッチでexを再スローすると、リストされた例外の1つだけがスローされることがコンパイラーに認識されるという素晴らしい機能があります。


Java 6以前

Java 7より前は、この問題を処理する方法がありますが、それらは洗練されておらず、制限がある傾向があります。

アプローチ#1

try {
     // stuff
} catch (Exception1 ex) {
     handleException(ex);
} catch (Exception2 ex) {
     handleException(ex);
}

public void handleException(SuperException ex) {
     // handle exception here
}

例外ハンドラーがtryの前に宣言されたローカル変数にアクセスする必要がある場合、これは面倒です。また、ハンドラーメソッドが例外を再スローする必要がある場合(およびチェックされる場合)、署名に重大な問題が発生します。具体的には、handleExceptionは、スローするSuperException ...として宣言する必要があります。これは、潜在的に、囲むメソッドの署名など​​を変更する必要があることを意味します。

アプローチ#2

try {
     // stuff
} catch (SuperException ex) {
     if (ex instanceof Exception1 || ex instanceof Exception2) {
         // handle exception
     } else {
         throw ex;
     }
}

ここでも、署名に潜在的な問題があります。

アプローチ#3

try {
     // stuff
} catch (SuperException ex) {
     if (ex instanceof Exception1 || ex instanceof Exception2) {
         // handle exception
     }
}

else部分を省略した場合(たとえば、現時点でSuperExceptionの他のサブタイプがないため)、コードはより脆弱になります。例外階層が再編成されると、elseのないこのハンドラーは、静かに例外を食べることになります!

194
Stephen C

Java <= 6.xでは、catchブロックごとに1つの例外をキャッチできます:

try {

} catch (ExceptionType name) {

} catch (ExceptionType name) {

}

ドキュメント:

各catchブロックは例外ハンドラーであり、引数で示される例外のタイプを処理します。引数タイプExceptionTypeは、ハンドラーが処理できる例外のタイプを宣言します。Throwableクラスから継承するクラスの名前でなければなりません。

Java 7の場合、1つのcatchブロックで複数の例外をキャッチできます:

catch (IOException|SQLException ex) {
    logger.log(ex);
    throw ex;
}

ドキュメント:

Java SE 7以降では、1つのcatchブロックで複数の種類の例外を処理できます。この機能により、コードの重複を減らし、過度に広範な例外をキャッチする誘惑を軽減できます。

参照:http://docs.Oracle.com/javase/tutorial/ essential/exceptions/catch.html

33

Java 7を使用していない場合は、例外処理をメソッドに抽出できます。これにより、少なくとも重複を最小限に抑えることができます。

try {
   // try something
}
catch(ExtendsRuntimeException e) { handleError(e); }
catch(Exception e) { handleError(e); }
12
jeff

Java SE 7のリリース前は、tryブロックに関連付けられた複数のcatchステートメントでコードを記述する習慣がありました。非常に基本的な例:

 try {
  // some instructions
} catch(ATypeException e) {
} catch(BTypeException e) {
} catch(CTypeException e) {
}

しかし、Javaの最新の更新により、複数のcatchステートメントを記述する代わりに、1つのcatch句内で複数の例外を処理できます。この機能を実現する方法を示す例を次に示します。

try {
// some instructions
} catch(ATypeException|BTypeException|CTypeException ex) {
   throw e;
}

そのため、1つのcatch句に複数の例外を含めると、コードが簡素化されるだけでなく、コードの冗長性も削減されます。この機能を実装とともに非常によく説明しているこの記事を見つけました。 Java 7からの改善された優れた例外処理 これもあなたを助けるかもしれません。

2
Saurab Parakh

Java <7の場合、Exceptionとともにif-elseを使用できます。

try {
    // common logic to handle both exceptions
} catch (Exception ex) {
    if (ex instanceof Exception1 || ex instanceof Exception2) {

    }
    else {
        throw ex;
        // or if you don't want to have to declare Exception use
        // throw new RuntimeException(ex);
    }
}

Throwableを編集して、例外に置き換えました。

2
Sarel Botha

http://docs.Oracle.com/javase/tutorial/essential/exceptions/catch.html は、同じブロックで複数の例外をキャッチすることをカバーしています。

 try {
     // your code
} catch (Exception1 | Exception2 ex) {
     // Handle 2 exceptions in Java 7
}

私は学習カードを作っていますが、このスレッドは役に立ちました。ちょうど2セントを入れたかっただけです。

1
Eli