39

私が間違っていなければ、例外のサブクラスを最初にキャッチする必要があります。しかし、RuntimeException と具体的なチェック済み例外をキャッチする必要がありますが、どちらを最初にキャッチする必要がありますか?

try {
    ...
} catch(RuntimeException e) {
    ...
} catch(IOException e) {
    ...
}

この順番は正しいですか?それとも正しいが悪い選択肢ですか?

4

3 に答える 3

72

順序は、最初に一致したものが実行されます( JLS が明確に説明しているように)。

最初のキャッチが例外に一致する場合は実行され、一致しない場合は次のものが試行され、一致するか一致しないまで何度も繰り返されます。

したがって、例外をキャッチするときは、常に最も具体的なものを最初にキャッチし、次に最も一般的なもの (RuntimeException または Exception) をキャッチする必要があります。たとえば、 String.charAt(index)メソッドによってスローされたStringIndexOutOfBoundsExceptionをキャッチしたいが、コードでNullPointerExceptionもスローされる可能性があるとします。例外をキャッチする方法は次のとおりです。

String s = null;
try {
  s.charAt(10);
} catch ( NullPointerExeption e ) {
  System.out.println("null");
  e.printStackTrace();
} catch ( StringIndexOutOfBoundsException e ) {
  System.out.println("String index error!");
  e.printStackTrace();
} catch ( RuntimeException e ) {
  System.out.println("runtime exception!");
  e.printStackTrace();
}

したがって、この順序で、例外が正しくキャッチされ、互いにつまずいていないことを確認しています.NullPointerExceptionの場合は最初のキャッチに入り、StringIndexOutOfBoundsExceptionの場合は2番目に入り、最後にそれ以外の場合RuntimeException (またはIllegalArgumentExceptionのようにそれを継承) は、3 番目のキャッチに入ります。

IOException は Exception から継承し、RuntimeException も Exception から継承するため、ケースは正しいため、互いにつまずくことはありません。

次のように、最初に一般的な例外をキャッチし、次にその子孫の 1 つを後でキャッチすることも、コンパイル エラーです。

try {
  // some code here
} catch ( Exception e) {
  e.printStackTrace();
} catch ( RuntimeException e ) { // this line will cause a compilation error because it would never be executed since the first catch would pick the exception
  e.printStackTrace();
}

したがって、最初に子を作成し、次に親の例外を作成する必要があります。

于 2012-06-09T22:00:41.090 に答える
4

この順番は正しいですか?それとも正しいが悪い選択肢ですか?

ない。他の回答が言っているように、コンパイラは、単純なキャッチを別のキャッチをマスクする順序で配置するかどうかを通知する必要があります。

しかし、コードには別の潜在的な問題があります。実際にキャッチする必要がありますRuntimeException。問題は、チェックされていない例外のソース/原因が多数あり、それらのソース/原因の多くが実際にはアプリケーションのバグであることです。

を使用してcatch緊急シャットダウンの一部として診断をログに記録することは問題ありませんが、 をキャッチしてから回復しようとする RuntimeException場合は、深刻な問題を隠蔽していないことに注意する必要があります。

  • 何があっても、例外とそのスタックトレースを必ずログに記録してください。

  • 回復を試みることが賢明かどうかを検討してください。未知のバグがある場合、例外をトリガーする前に予測できない損害を与えた可能性があります。アプリケーションが回復できるかどうか、または続行しようとすることでさらに大きな損害を与える可能性があるかどうかを知る方法はありません。

同じアドバイスがキャッチExceptionThrowable/にも当てはまりますError。そして、それはより重要ですThrowable/Errorすでに発生している可能性のある損傷の性質のために.

于 2012-06-10T03:10:54.460 に答える
0

コンパイラが受け入れる任意の順序は正しいです。

于 2012-06-09T22:00:12.307 に答える