この質問にはすでに答えがあります。
いくつかの従来のコードでは、私はこれを見ています。オーバーブロードな例外がキャッチされ、そして再び投げられています。これは良い習慣ですか?するthrow e;
同じ例外を再スローするか、新しい例外を作成しますか。
catch (Exception e) {
StringBuilder sb = new StringBuilder(
"Oops. Something went wrong with id: ");
sb.append(id);
sb.append(". Exception is: ");
sb.append(e.toString());
System.out.println(sb.toString());
throw e;
}
throw e
同じ例外を再スローしています。少なくとも元のスタックトレースを保存します。何が起こったのかについての情報を記録した標準出力にメッセージを書いてから、元の例外を途中で進行させるだけです。
これは良い習慣ではありません。例外を中央の場所に記録し、それらのスタックトレースを記録するだけで十分なはずです。より多くの情報を追加する必要がある場合(例のように、IDをログに記録する場合)、元の例外を原因として新しい例外にネストしてから、新しい例外をスローすることをお勧めします。これはおそらく集中ログがない状況や例外がどこかで食いつく傾向がある状況で起こると思います。
rethrowing
異なるクライアントはこれらの例外を異なる方法で処理しようと試みるかもしれないので、例外は実際には良いかもしれません。同意しませんか。 - Prateek
これは通常悪い習慣です。catch(Exception e)
(時々呼ばれるポケモン例外処理ときのためにあなたはそれらすべてをキャッチしなければならない)キャッチすべての単一の例外そのような例外処理は、以下の理由であまり役に立ちません。
あなたのメソッドシグネチャは今public void whatever() throws Exception
これはめったに役に立ちません。これでチェーンの上位にあるものすべてが、どのような例外をスローしたのかわからなくなります。彼らはしなければならないでしょうinstanceof
特定の例外をすべてキャッチするという目的を完全に無効にします。
あなたの2番目の例外に関する限り、throw e;
同じ例外オブジェクトをスローします。例外をラップしたい場合は、新しい例外を作成できます。つまり、次のようにします。throw new MyCustomException(e);
。メソッドシグネチャも変更する必要があります。
それ以上連鎖がない場合は、これはそれほど悪くはないと思います(それでもまだ素晴らしいとは言えません)。スローされたすべての例外をログに記録しようとしているメソッドのように見えます。ただし、これを行うにはもっと良い方法があります。
私が一番思うのは、それが2層の保護を得ようとしていることでしょう。エラーメッセージが表示されていることを確認し、クライアントに例外の処理方法を要求します。catch
句は例外から回復するために何もしていません。
私はそれを良い/悪い習慣とは考えません。あなたの要件に応じて、あなたはあなたのAPIを使用している100の異なるクライアントがあり、それらのそれぞれが異なる方法から回復する異なる方法を持っているかもしれないようにどちらかの方法で進むと考えることができますexception
。何が問題なのかを表示することで、クライアントがどのように処理するかを決定する層のすぐ下にデフォルトのアクション層を追加します。exception
。
さて、あなたの質問に戻りましょう。おもうthrow e
同じ例外オブジェクトをスローします。例外としてobjects
Javaではあなたが作成する必要がありますnew exception object
あなたができる前にthrow
それは私があなたのコードで起こっているのを見ることができないそれです。
throw e
同じ例外が発生します。これを行う理由があったかもしれませんが、しない理由もあります。サンプルコードでは、メッセージがに送信されます。System.out
しかし、後でスタックトレースが表示された場合System.err
それは同期されません、そして実際には2つはあなたのコンソールに織り込まれるかもしれません。
より良い方法は次のとおりです。
catch (Exception e) {
StringBuilder sb = new StringBuilder(
"Oops. Something went wrong with id: ");
sb.append(id);
sb.append(". Exception is: ");
sb.append(e.toString());
throw new Exception(sb.toString(), e); // The original exception is an argument
}
これは新しいを作成しますException
修正されたメッセージで、そしてオリジナルを追加するException
デバッグに役立つスタックトレースへ。
それは良い習慣です。私はいつもに変換を使用すると思いますRuntimeException
試作中です。その後、必要があれば、これをより良い例外処理に変えることができます。この私の目的のためにグアバには以下のユーティリティクラスがあります。使い捨てこれは例外伝播を引き起こします。
しかしあなたの場合は例外はランタイム例外に変換なぜなら、一般を投げるメソッドを宣言するからです。Exception
スローするメソッドとまったく同じです。RuntimeException
コーリングパーティのため。最初のケースではそれすべてをキャッチ「後者ではそれ」何でもキャッチ'。実際のアプリケーションでは、これら2つの違いはまだ経験していません。だから私は好きですRuntimeException
入力が少なくて済むのでs。
キャッチException
Error
しかし左)キャッチRuntimeException
RuntimeException
- これはまたたくさん私が大事にしているのは、Exception
あなたは本当にこれらすべてのケースを扱うことはできません。それで、あなたがそれをにラップした場合、それは発呼者のための少ないタイピングを除いて違いを生じません。RuntimeException
。
Exception
投げることと同じではありませんRuntimeException
。前者がチェックされているので、メソッドシグネチャに記載する必要があります。のサブクラスである例外Exception
しかしではないのサブクラスRuntimeException
チェック例外です。 - Vivin PaliathException
すべてを捕捉することを意味します。キャッチRuntimeException
何かをキャッチすることを意味します。 2つのケースで実際の違いが見られることはまだありません。 - Andrey ChaschevException
その場合、呼び出し元はそれを処理するか再スローする必要がありますが、メソッドがスローされている場合はどちらも実行する必要はありません。RuntimeException
。キャッチもRuntimeException
「何かを捕まえる」という意味ではありません。それのみのサブクラスである例外をキャッチします。RuntimeException
(そしてRuntimeException
自体);確認済みの例外が検出されませんでした。 - Vivin PaliathException
Javaでは悪い習慣であるため、実際の例を考えるのは本当に難しいでしょう。を伝播するRuntimeException
しかし、アンチパターンではありえないし、それは良い習慣になり得る。 - Andrey Chaschev