12

次のJavaコードについて考えてみます。

try{

    // do something
    // this piece of code throws several checked exceptions.

} catch (IllegalArgumentException e) {
    handleException(e);
} catch (IllegalAccessException e) {
    handleException(e);
} catch (InvocationTargetException e) {
    handleException(e);
} catch (InstantiationException e) {
    handleException(e);
} catch (NoSuchMethodException e) {
    handleException(e);
} catch (IOException e) {
    handleException(e);
} catch (NoSuchFieldException e) {
    handleException(e);
}

ブロック内のコードは、tryいくつかのチェックされた例外をスローします。私がしたいのは、例外が発生したときにメッセージをログに記録することです(いくつかのカスタムメッセージ文字列を使用)。つまり、私の例外処理ロジックはすべての例外で同じです。

上記のコードは見栄えが良くないように感じます(LOCが増え、読みやすさが低下します)。

そのような場合を処理するためのより良い方法はありますか?

次の解決策はベストプラクティスではないため、推奨されません(チェックスタイルによる)。

try{
    // do something very bad
} catch (Exception e) {
    handleException(e);
} 
4

8 に答える 8

16

Java 6 では、すでに提案したものよりもはるかに魅力的なオプションはありません。

ただし、Java 7 には、使用できるmulti-catchステートメントがあります。

catch(IllegalArgumentException | IllegalAccessException | IOException exception) {
    handleException(e);
}
于 2012-07-16T18:24:52.240 に答える
6

あなたの場合、2番目のオプションでうまくいくと思います。すべてのケースで例外処理が同じであれば、コードを過度に複雑にする必要はありません。

于 2012-07-16T18:25:17.017 に答える
3

Java 7 には、新しい優れたソリューションがあります。次のように記述できます。

try{

    // do something
    // this piece of code throws several checked exceptions.

} catch (IllegalArgumentException | IllegalAccessException | InvocationTargetException e) {
    handleException(e);
} catch ...

古いバージョンの Java では、共通のサブクラスをキャッチExceptionすること (これは 1 つのケースです) は、実際には悪い考えではありません。何も考えずにいつもやってしまうのは悪いことですが、よく考えて最善の解決策として選択したのであれば、それを実行してもかまいません。

于 2012-07-16T18:25:24.063 に答える
3

Java 6 以下では何もする必要はありません。

Java 7 では、次のようなことができます。

catch(InstantiationException | IOException | NoSuchFieldException exception) {
        // handle our problems here.
}

Java 6 では、別の「悪い習慣」(ただし、役に立つかもしれません) は次のようになります。

catch (Exception e) {
   if(! e instanceof RuntimeException) // Only non-checked exceptions!
       throw e;
   handleException(e) // All checked exception.
}

問題: instanceof を使用しています。しかし、あなたのコードはより良く見えます...

于 2012-07-16T18:26:03.223 に答える
3

これは、チェック例外が Java プログラマーの生活を悲惨なものにするもう 1 つの例です。とりわけ、コードの一部がチェック済み例外をスローする可能性があるという理由だけで、その特定のコードはおそらく、それらを処理したい場所ではありませんアプリが適切に設計されている場合、例外を処理 (ログ) する中心的な場所である例外バリアが既に存在します。その場合は、これらすべての例外を にラップRuntimeExceptionして、バリアに渡す必要があります。その場合の処理​​コードは次のとおりです。

try {
  // do stuff
} catch (RuntimeException e) { 
  throw e; 
} catch (Exception e) { 
  throw new RuntimeException(e); 
}
于 2012-07-16T18:29:57.793 に答える
1

皆さんは、このソリューションについてどう思いますか?

try {
    // some code that might throw an exception.
} catch (Exception e) {
    if(e instanceof RuntimeException){
        throw (RuntimeException) e;
    }
    // log exception
}

長所:

  1. コードが少なく、すべてのチェック済み例外に対して同じ例外処理ロジックを維持できます。
  2. 実行時の例外とエラーを処理しません。それらをキャッチしますが、それらを投げ返します。

短所:

  1. それでも例外がキャッチされるため、ベスト プラクティスチェックを確認しないでください。(ただし、実行時の例外をキャッチするシナリオは考慮されますが、チェック スタイルは失敗する可能性があります。)
  2. RuntimeExceptionへのダウンキャストで考えられる副作用はありますか?
于 2012-07-17T18:42:51.227 に答える
0

あなたのコードは、これを行うつもりだったようです:

try{
    // do something very bad
} catch (Throwable e) {
    handleException(e);
}

これは、すべての例外だけでなく、エラー (try/catch ブロック内でスローされる可能性のあるすべてのもの) もキャッチします。

すべての例外をキャッチしてすべてのエラーを通過させることが正しいことはめったにありませんが、任意に選択された無関係な例外の長いリストをキャッチすることは、正しいことである可能性はさらに低くなります。

例外のリストはかなり疑わしいようです。つまり、IllegalArgumentException をキャッチするのに、意味的に同じレベルの NullPointerException または ClassCastException をキャッチしないのはなぜですか。また、IO と組み合わせて Reflection を使用しているようですので、NoClassDefFoundError、ExceptionInInitializerError などのエラーにも対処する必要があるかもしれません。また、StackOverflowError や OutOfMemoryError についてはどうでしょうか ...

于 2012-07-17T03:54:44.347 に答える
0

Java 7 チームのメンバーがあなたの不満を聞いたようです :-) http://www.oracle.com/technetwork/articles/java/java7exceptions-486908.html

于 2012-07-16T18:27:15.187 に答える