116

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

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

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

4

6 に答える 6

215

Java7以降

Java 7以降、複数例外のキャッチがサポートされています。

構文は次のとおりです。

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

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


Java6以前

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は、throwing 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例外を黙って食べてしまう可能性があります。

于 2012-06-26T15:58:45.870 に答える
34

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

try {

} catch (ExceptionType name) {

} catch (ExceptionType name) {

}

ドキュメンテーション:

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

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

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

ドキュメンテーション:

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

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

于 2012-06-26T16:09:05.707 に答える
12

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

try {
   // try something
}
catch(ExtendsRuntimeException e) { handleError(e); }
catch(Exception e) { handleError(e); }
于 2012-06-26T16:04:54.977 に答える
2

Java <7の場合、例外とともに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を編集して例外に置き換えました。

于 2012-06-26T18:14:19.013 に答える
2

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

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

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

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

したがって、単一のcatch句に複数の例外があると、コードが単純化されるだけでなく、コードの冗長性も低下します。この機能とその実装について非常によく説明しているこの記事を見つけました。 Java7からの改善されたより良い例外処理 これもあなたを助けるかもしれません。

于 2014-01-31T19:56:21.320 に答える
1

http://docs.oracle.com/javase/tutorial/essential/exceptions/catch.htmlは、同じブロック内の複数の例外のキャッチについて説明しています。

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

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

于 2013-02-08T18:15:52.360 に答える