throws
メソッドに句を追加するか、または を使用するかを決定する際の一般的な経験則は何try-catch
ですか?
私が自分で読んだことからthrows
、呼び出し元が契約の終わり(渡されたオブジェクト)を破ったときにtry-catch
使用する必要があり、メソッド内で実行されている操作中に例外が発生したときに使用する必要があります。これは正しいです?もしそうなら、呼び出し側で何をすべきですか?
PS: Google と SO で検索しましたが、これについて明確な回答が必要です。
throws
メソッドに句を追加するか、または を使用するかを決定する際の一般的な経験則は何try-catch
ですか?
私が自分で読んだことからthrows
、呼び出し元が契約の終わり(渡されたオブジェクト)を破ったときにtry-catch
使用する必要があり、メソッド内で実行されている操作中に例外が発生したときに使用する必要があります。これは正しいです?もしそうなら、呼び出し側で何をすべきですか?
PS: Google と SO で検索しましたが、これについて明確な回答が必要です。
一般に、関連する問題をローカルで処理できない場合、メソッドは呼び出し元に例外をスローする必要があります。たとえば、メソッドが指定されたパスのファイルから読み取ることになっている場合、IOExceptions
適切な方法でローカルに処理することはできません。無効な入力にも同じことが当てはまります。私の個人的な選択はIllegalArgumentException
、この場合のように未チェックの例外をスローすることです。
そして、次の場合、呼び出されたメソッドから例外をキャッチする必要があります。
DAO
使用を示したくないため、Hibernate
すべてをローカルでキャッチしHibernateExceptions
、それらを独自の例外タイプに変換します)。これが私がそれを使用する方法です:
スロー:
トライキャッチ:
よりクリーンなため、常にスローを使用する多くの人を知っていますが、コントロールがほとんどありません。
そのための私の個人的な経験則は簡単です:
try/catch
。それを処理するとは、ユーザーに通知したり、エラーから回復したり、より広い意味で、この例外がコードの実行にどのように影響するかを理解できることを意味します。注 : この返信はコミュニティ ウィキになりました。自由に情報を追加してください。
メソッドに try-catch または throws 句を追加するかどうかの決定は、「例外をどのように処理するか (または処理する必要があるか)」によって異なります。
例外を処理する方法は幅広く、簡単な質問からはほど遠いものです。これには、例外を処理する場所と、catch ブロック内で実装するアクションの決定が特に含まれます。実際、例外を処理する方法は、グローバルな設計上の決定である必要があります。
したがって、あなたの質問に答えると、経験則はありません。
例外を処理する場所を決定する必要があり、その決定は通常、ドメインとアプリケーションの要件に非常に固有のものです。
例外が発生したメソッドに、それを処理するのに十分な量の情報がある場合は、キャッチして、何が起こったのか、どのデータが処理されていたのかについての有用な情報を生成する必要があります。
簡単に説明します。呼び出されたメソッドが例外の原因ではないと思われる場合は、スローを使用します (たとえば、呼び出し元メソッドからの無効なパラメーター、検索対象のアイテム、コレクションで使用できないフェッチ、またはデータリストのフェッチ)。呼び出されたメソッドの機能によって何らかの例外が発生する可能性があると思われる場合は、try catch ブロック (呼び出されたメソッドで例外を処理する) を使用します。
throws
メソッドは、オブジェクトの状態、メソッドに渡されるパラメーター、およびメソッドが作用するその他のオブジェクトを取り巻く合理的な保証を行うことができる場合にのみ、例外にする必要があります。たとえば、呼び出し元がコレクションに含まれていると予想されるアイテムをコレクションから取得することになっているメソッドはthrows
、コレクションに存在すると予想されていたアイテムが存在しない場合、チェック例外になる可能性があります。その例外をキャッチする呼び出し元は、コレクションに問題のアイテムが含まれていないことを期待する必要があります。
Java では、適切な型の例外をスローすると宣言されたメソッドを介してチェック済み例外がバブルアップすることを許可しますが、そのような使用法は一般的にアンチパターンと見なされるべきであることに注意してください。たとえば、あるメソッドLookAtSky()
が を呼び出すと宣言されFullMoonException
ていて、満月になったときにそれをスローすることが期待されているとします。としても宣言されている をLookAtSky()
呼び出すことをさらに想像してみてください。aが によってスローされ、それをキャッチせず、それを処理するか、他の例外タイプでラップしなかった場合、呼び出されたコードは、例外が地球の月が満杯である結果であると想定します。木星の衛星の 1 つが原因である可能性があるという手がかりはありません。ExamineJupiter()
throws FullMoonException
FullMoonException
ExamineJupiter()
LookAtSky()
LookAtSky
呼び出し元が処理することを期待する可能性のある例外 (本質的にすべてのチェック済み例外を含む) は、その例外が呼び出されたメソッドに対して意味するのと同じことをメソッドの呼び出し元に意味する場合にのみ、メソッドを介して浸透できるようにする必要があります。コードが何らかのチェック済み例外をスローすると宣言されているメソッドを呼び出したが、呼び出し元が実際にその例外をスローすることを期待していない場合 (たとえば、事前に検証されたメソッド引数を想定しているため)、チェック済み例外をキャッチしてラップする必要があります。いくつかの未チェックの例外タイプで。呼び出し元が例外がスローされることを予期していない場合、呼び出し元は例外が特定の意味を持つことを期待できません。