80

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

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

PS: Google と SO で検索しましたが、これについて明確な回答が必要です。

4

11 に答える 11

62
  • 意味のある方法で例外を処理できる場合にのみ、例外をキャッチします
  • 現在のメソッドのコンシューマーによって処理される場合、例外を上向きにスローすることを宣言します
  • 入力パラメーターが原因である場合は例外をスローします (ただし、これらはチェックされないことが多い)
于 2010-07-08T12:05:59.573 に答える
15

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

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

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

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

スロー:

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

トライキャッチ:

  • エラーごとにプログラムの動作を変えたい場合。
  • エンド ユーザーに意味のあるエラーを提供したい場合に 最適です。

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

于 2010-07-08T12:15:24.843 に答える
9

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

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

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

于 2010-07-08T12:06:08.247 に答える
3

メソッドに try-catch または throws 句を追加するかどうかの決定は、「例外をどのように処理するか (または処理する必要があるか)」によって異なります。

例外を処理する方法は幅広く、簡単な質問からはほど遠いものです。これには、例外を処理する場所と、catch ブロック内で実装するアクションの決定が特に含まれます。実際、例外を処理する方法は、グローバルな設計上の決定である必要があります。

したがって、あなたの質問に答えると、経験則はありません。

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

于 2013-06-13T13:24:15.467 に答える
2

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

于 2010-07-08T12:06:12.240 に答える
1

簡単に説明します。呼び出されたメソッドが例外の原因ではないと思われる場合は、スローを使用します (たとえば、呼び出し元メソッドからの無効なパラメーター、検索対象のアイテム、コレクションで使用できないフェッチ、またはデータリストのフェッチ)。呼び出されたメソッドの機能によって何らかの例外が発生する可能性があると思われる場合は、try catch ブロック (呼び出されたメソッドで例外を処理する) を使用します。

于 2021-01-19T09:00:19.040 に答える
1

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

Java では、適切な型の例外をスローすると宣言されたメソッドを介してチェック済み例外がバブルアップすることを許可しますが、そのような使用法は一般的にアンチパターンと見なされるべきであることに注意してください。たとえば、あるメソッドLookAtSky()が を呼び出すと宣言されFullMoonExceptionていて、満月になったときにそれをスローすることが期待されているとします。としても宣言されている をLookAtSky()呼び出すことをさらに想像してみてください。aが によってスローされ、それをキャッチせず、それを処理するか、他の例外タイプでラップしなかった場合、呼び出されたコードは、例外が地球の月が満杯である結果であると想定します。木星の衛星の 1 つが原因である可能性があるという手がかりはありません。ExamineJupiter()throws FullMoonExceptionFullMoonExceptionExamineJupiter()LookAtSky()LookAtSky

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

于 2013-06-13T19:16:38.510 に答える