web-dev-qa-db-ja.com

nullポインター例外のキャッチ

私はJavaについてこの主旨を尋ねていますが、それは言語のホスト全体に当てはまると思います。

考えて、

if(myVariable==null){
       doSomethingAboutIt();
}
else carryOn(myVariable);

そして

try{
     carryOn(MyVariable);
}catch(NullPointerException e ){
      doSOmethingAboutIt();}

これらのコードブロックはどちらも基本的に同じですか? 2番目のアプローチを選択する理由はありますか?もちろん、myVariableがnullになることは決してないでしょうが、それを確認する最善の方法は、単純なifステートメントを実行することです。

14
user485498

私の立場から、これら2つのコードブロックを意図的に同等と見なすのはためらいがあります。もちろん、それらは同じエラー処理を行いますが、それは何よりも開発者の決定です。

私にとって、iftestingであり、値を使用できるかどうかを確認し、使用できない場合は問題を回避しています。 try...catch block is assuming値は有効であり、有効でない場合は、フォールスルーして異常な動作を回避します。

例外は、異常なプログラム破壊コード(ゼロ除算など)が発生した場合に主に検討する必要があります。

10
Makoto

いいえ、それらのコードブロックはまったく同じではありません。

最初のコードブロックでは、myVariablenullであるかどうかを確認し、1つの時点でそれを実行しています。その後、myVariablenullになり、最終的にNullPointerExceptionをスローする場合があります。この場合、2番目のコードスニペットは例外をキャッチしますが、最初のコードスニペットは例外をキャッチしません。

さらに、2番目のコードスニペットはNullPointerExceptionsをキャッチします。これは、carryOn(myVariable)呼び出しの結果として、コールスタックのどこからでもスローされる可能性があります。これはひどい;特定の変数がnullであるという前提の下で動作する例外を、それが完全に別の何かである場合に飲み込んでいます。

最初のコードスニペットを使用します。

4
cheeken

例外は、例外的な発生に対してのみ使用します。 2番目のブロックではなく、最初のコードブロックを使用してください。

まあ、それ自体では、carryOn内の他の何かがnullインスタンスのメソッドまたはプロパティの呼び出しを参照していない限り、carryOn(MyVariable);はNPEをスローしません。

例外の生成にはスタックトレースの生成が必要になるなど、例外のキャッチは最初にそれをチェックするよりも計算コストがかかります。

私はそれが「よりクリーンな」コードにもなると主張します。

参照:- Java try/catchパフォーマンス。try句の内容を最小限に抑えることをお勧めしますか? - Try Catch Performance Java

2
ziesemer

最初のアプローチは、パフォーマンスの低下を招くため、例外をキャッチするよりも優れています。私の意見では、最善のアプローチは Null Object pattern を適用することです。 Guavaライブラリは、独自に作成する代わりに活用できる オプション クラスを提供します。

0