web-dev-qa-db-ja.com

スローまたはトライキャッチ

メソッドにthrows句を追加するか、try-catchを使用するかを決定する際の一般的な経験則は何ですか?

私が読んだことから、呼び出し元が契約の終わりを破ったとき(渡されたオブジェクト)はthrowsを使用し、操作中に例外が発生したときはtry-catchを使用する必要がありますメソッド内で実行されています。これは正しいです?もしそうなら、発信者側で何をすべきですか?

追伸:Googleで検索し、SOですが、これについては明確な回答が必要です。

70
James P.
  • 意味のある方法で処理できる場合にのみ例外をキャッチする
  • 現在のメソッドのコンシューマーによって処理される場合は、例外を上方向にスローすることを宣言します
  • 入力パラメーターが原因である場合は例外をスローします(ただし、これらは多くの場合チェックされません)
54
Bozho

一般に、メソッドは、関連する問題をローカルで処理できない場合、呼び出し元に例外をスローする必要があります。例えば。メソッドが指定されたパスのファイルから読み取ることになっている場合、IOExceptionsは適切な方法でローカルに処理できません。無効な入力にも同じことが当てはまりますが、この場合、IllegalArgumentExceptionのような未チェックの例外をスローするのが個人的な選択であると付け加えています。

そして、以下の場合、呼び出されたメソッドから例外をキャッチする必要があります。

  • ローカルで処理できるものです(たとえば、入力文字列を数値に変換しようとします。変換が失敗した場合、代わりにデフォルト値を返すことは完全に有効です)。
  • または、例外をスローしないでください(例:例外が実装固有の下位層から来ている場合、その実装の詳細は呼び出し元に表示されるべきではありません。たとえば、DAOが使用することを表示したくないHibernateはエンティティを永続化するため、すべてのHibernateExceptionsをローカルでキャッチし、独自の例外タイプに変換します)。
14
Péter Török

私の個人的な経験則は簡単です:

  • 意味のある方法(コメントから追加)を処理できますか?したがって、コードをtry/catch。それを処理することにより、ユーザーにエラーを通知したり、エラーから回復したり、より広い意味で、この例外がコードの実行にどのように影響するかを理解できるようになります。
  • 他の場所で、それを捨てます

注:この返信はコミュニティwikiになりました。気軽に情報を追加してください。

9
Riduidel

これが私がそれを使用する方法です:

スロー:

  • エラーが発生したときにコードを停止するだけです。
  • 特定の前提条件が満たされていない場合にエラーが発生しやすい方法に適しています。

トライキャッチ:

  • プログラムが異なるエラーで異なる動作をするようにする場合。
  • 意味のあるエラーをエンドユーザーに提供したい場合に最適です。

Throwsはよりクリーンであるため、常にThrowsを使用する多くの人々を知っていますが、コントロールはほとんどありません。

7
Justian Meyer

メソッドにtry-catch節またはthrows節を追加する決定は、「例外を処理する方法(または処理方法)」に依存します。

例外をどのように処理するかは、些細な質問から広く答えられます。特に、例外を処理する場所とcatchブロック内で実装するアクションの決定が含まれます。実際、例外をどのように処理するかは、グローバルな設計上の決定である必要があります。

だからあなたの質問に答えると、経験則はありません。

例外を処理する場所を決定する必要があり、その決定は通常、ドメインとアプリケーションの要件に非常に固有です。

3
EijiAdachi

例外が発生したメソッドに対処するのに十分な情報がある場合、メソッドはキャッチし、何が発生し、どのデータが処理されているかに関する有用な情報を生成する必要があります。

2

何を使用するか。これについてよく調べました。厳格なルールはありません。

「しかし、開発者として、チェック済み例外はメソッドのthrows句に含める必要があります。これは、コンパイラがチェックする例外を知るために必要です。慣習により、未チェック例外はthrows句に含めないでください。
それらを含めることは、プログラミングの貧弱な実践と見なされます。コンパイラはそれらをコメントとして扱い、チェックしません。」

出典:キャシー・シエラによるSCJP 6本

1
sofs1

メソッドは、オブジェクトの状態、メソッドに渡されるパラメーター、およびメソッドが動作する他のオブジェクトを取り巻く合理的な保証を行うことができる場合にのみ、例外をthrowsする必要があります。たとえば、呼び出し元がその中に含まれることを期待しているアイテムをコレクションから取得することになっているメソッドは、コレクションに存在すると予想されるアイテムがチェックされない場合、throwsになります。その例外をキャッチする呼び出し元は、問題のアイテムがコレクションに含まれていないことを期待する必要があります。

Javaを使用すると、チェックされた例外が適切なタイプの例外をスローするように宣言されたメソッドを介してバブルアップできますが、そのような使用法は一般にアンチパターンと見なされる必要があります。たとえば、いくつかのメソッドLookAtSky()FullMoonExceptionを呼び出すと宣言されており、月が一杯になったときにスローすることが期待されています。さらに、LookAtSky()ExamineJupiter()throws FullMoonExceptionとしても宣言されます。FullMoonExceptionExamineJupiter()によってスローされ、LookAtSky()がキャッチせず、それを処理するか、他の何かにラップする場合例外タイプ、LookAtSkyを呼び出したコードは、例外が地球の月がいっぱいになった結果であると仮定します;木星の月の1つが犯人であるかもしれないという手掛かりがありません。

呼び出し元が処理することが予想される例外(本質的にすべてのチェック済み例外を含む)は、例外が呼び出されたメソッドを意味するのと同じことをメソッドの呼び出し元に意味する場合にのみ、メソッドを介して浸透することを許可する必要があります。コードが何らかのチェック例外をスローするように宣言されているメソッドを呼び出すが、呼び出し側が実際にその例外をスローすることを期待していない場合(たとえば、事前に検証されたメソッド引数と考えるため)、チェック例外をキャッチしてラップする必要がありますいくつかの未チェックの例外タイプ。呼び出し元が例外がスローされることを期待していない場合、呼び出し元は特定の意味を持つことを期待できません。

1
supercat

try-catchペアは、例外が発生した場合にカスタマイズ動作を提供したい場合に使用されます.....言い換えれば...プログラム要件に従って問題の解決策があります(例外発生)。 。

ただし、例外発生のケースに関する具体的な解決策がない場合は、throwsが使用されます。プログラムの異常終了を取得したくないだけです。

それが正しいことを願っています:-)

0
user8148636

Try catchを使用すると、例外が発生しても残りのコードが実行されます。

例外をスローするようにメソッドを指定した場合、例外が発生すると、コードの実行がすぐに停止します。

0
Jarkid