2011-01-17 11 views
13

NullPointerExceptionをキャッチすることが悪い習慣であると聞いたことがあります。私はそれが分かりやすいと思います。 NullPointerExceptionを先頭に伝播させると、何かが間違っていることが検出されます。しかし、多くの場合、多くの友人がExceptionを直接キャッチしているので、上記のコードで発生する可能性のあるさまざまな種類の例外をすべて気にする必要はありません。これは良い練習ですか?未処理のまま残されている他の種類の例外は何ですか?それに加えて、例外の原因がわかっている特定のコードに対してNullPointerExceptionを処理することも意味があります。例外はいつ処理されるのですか?処理されないのはいつですか?そして、未処理のまま残されている例外の可能なリストは何でしょうか?nullポインタの例外をキャッチするのが良い方法ではない場合、例外をキャッチするのは良い方法ですか?

+3

"NullPointerExceptionをキャッチするのは悪い習慣だと聞いたことがありますが、それは分かりやすいと思います。NullPointerExceptionを上に伝播させると、何かが間違っていることを検出できます。 。あなたは「嚥下」と「キャッチ」を混同していませんか? – leonbloy

+2

'NullPointerException'をキャッチして何かをしても問題はありません。これは例外になります。一般的な考え方は、扱うことができる例外をキャッチし、処理できない例外をキャッチ(破棄)しないことです。だから私はあなたが聞いたことに同意しなければなりません。 –

答えて

20

ポケモンの例外処理が悪いです。特に、それが空のブロックであり、単にそれらを飲み込んでいるのであれば。特定のコンテキスト内の特定のものを実際に意味しているという理由で、具体的に型指定された例外があります(本質的に、何が間違っているかを伝えています)。だから、Exceptionを捕まえることによって、あなたはその例外が何であるか気にしないこと、そして何が起こったのか気にしないと言っています。これはおそらくあなたが望むものではありません。一般的に

、キャッチ例外は次の規則に従ってください。

  • このレベルで例外を処理する意味がありますか?はいの場合は、それを処理します。そうでない場合は、伝搬します。
  • 第1のルールと併せて、「取り扱い」は、捕捉、ラッピング、再投げを意味することもできます。これは抽象度のリークを防ぐためのもので、メソッドの呼び出し側は基本的な実装について知る必要はありません。
  • 空のキャッチブロックは、例外を処理したことを意味しません。それは「嚥下」と呼ばれています。最低でも、例外をログに記録する必要があります。時々例外が発生するのは実際にはあなたのコードの論理的な流れの一部なので、特別なことをしたいかもしれません(ただし、これはルールではなく例外です)例外を引き起こす状況を調べる方が良いあなたのコードの論理的な流れにそれらを組み込むのではなく)。

あなたのコードでヌル値を簡単にチェックできるので、ヌルポインタ例外を明示的にキャッチする必要はありません。 NullPointerExceptionを起こさせるのは意味がありません(悪い習慣です)。 NullPointerExceptionをスローするコードがあり、コントロールできず修正できないコードであっても、NullPointerExceptionの原因となる入力パラメータを特定し、具体的にテストする必要があります。

キャッチすべきではないもう1つの例外はIllegalArgumentExceptionです。この例外は、意味をなさない引数を渡したことを意味します。この例外をキャッチする代わりに、明示的に入力パラメータをテストして、それらが正常であり、IllegalArgumentExceptionが発生しないことを確認する必要があります。

+12

「ポケモンの例外処理」とは何ですか? –

+25

catch(Exception ex){それらをすべてキャッチしたいとき。 –

+0

"ポケモンの例外処理":Gatcha Catch 'Em All:D – tkr

5

これを行うことで値を追加できる場合は、例外をキャッチする必要があります。それ以外の場合は、発信者に渡す必要があります。

通常、NullPointerExceptionは、コード内のバグの結果です。キャッチブロックでこれをどのようにしっかりと修正できますか?

例外については気にされていません。

0

あなたの例外を処理するための優雅なやり方があれば、それをキャッチすると便利です。

+1

そうでない場合は、最終的に例外が記録されます。 –

1

例外をキャッチする主なルールは、なぜこれを行うのか知っておく必要があるということです。例外クラスは、プログラマが一般的なエラー処理を行いたいときに捕捉されます。実際に何が起こったのかはまったく気にしません。その場合、彼はトランザクションをロールバックするか、何らかのクリーンアップを行うことを決定するかもしれません。 特定の例外をキャッチする場合は、同じルールを適用してみてください。私はあなたがなぜそれをやっているのか正確に知っています。しかし、誰かがNPEの場合に本当に特別なことをしたいと思うことは非常にまれです。

8

NullPointerExceptionを捕まえているという「理由」は、何かがうまくいかないときにバブルアップさせることになっているため、悪い習慣とはみなされません!例外を言うと、その型だけに基づいて「最も処理されないまま残っている」というのは悪い考えです。

NPEはプログラミングエラーの結果と見なされます。厳密に正しいプログラムは決して生成してはいけません。なぜなら、コードが1つを投げたことを意味し、プログラマは最初にそれを引き起こした壊れたコードを修正するのではなく、それを隠して隠すことに決めたからです。

たとえば、ビジネス上の理由から、バグが内部にあり、時にはヌルポインタがスローされたAPIに結合された場合、それを捕まえたり、メッセージ。誰かが「Null Pointer Exceptionを捕まえていない」と言っただけでUIをヒットさせるのは意味をなさないでしょう!

キャッチjava.lang.Exceptionは特定のケースで正当である可能性がありますが、一般的に「私は怠け者です」はその1つではありません。 :)たとえば、APIを実装していて、仕様にない例外が出てこないことを絶対に確かめたい場合は、Exceptionをキャッチして、定義したアプリケーション例外でラップします。

3

通常、例外をキャッチする必要があるのは、意味のある方法で処理できる場合のみです。あなたができないならば、それをトップにバブルさせてプロセスを終了させるだけです。たとえば、NullPointerExceptionやI/Oエラーから意味のある方法で回復できますか?私はそうは思わない。例外処理のための

マイルール:あなたには、いくつかの意味のある方法でそれらを処理することができない限り、一般的には

  • は、例外をキャッチしません。
  • プロセス/マシンの境界で例外をキャッチし、キャッチされた例外を利用可能なコンテキストとともにログに記録し、再スローします。例外がカスタム例外の場合、呼び出すプロセスに既知の/有用な型を例外としてラップし、それをスローすることができます。
  • また、実行可能なコンテキストが最も利用可能な低レベルで例外をキャッチし、例外と関連するコンテキストを記録してから例外を再試行することもできます。
  • 再送するときはthrow caughtException ;ではなくthrow ;を使用してください。前の構文を使用すると、元のスタックトレースが保持されます。後者の構文を使用すると、throw caughtException ;で始まる新しいスタックトレースが作成されます。例外が検出された時点までのすべてのコンテキストと呼び出しスタックを失います。
  • このように選択すると、例外を上位レベルで捕捉し、プロセスを正常に終了し、例外情報をログに記録して根本的な問題のデバッグと修正に役立てることができます。

(可能な場合)フロー制御メカニズムとして例外を使用しないでください。例外は自然界では例外的です。むしろ、呼び出すすべてのメソッドの呼び出し元の契約の終了(前提条件)を前提に強制します。

詳細については、Bertrand Meyersの書籍Object Oriented Software Construction, 2nd ed.を参照してください。

+1

「再スローするとき」:Javaでは「投げる」ことはできません。それを行うときにスタックトレースを失うことはありません。 – hjhill

関連する問題