2017-07-26 6 views
9

私はJavaコード内で多くの守備型ヌルチェックを使用しています。彼らは目的を十分に果たしていますが(ほとんどの場合)、「醜い」見た目のコードでは大きな犠牲を払っています。Java:オブジェクトに対してヌルチェックをスキップする場合

いつもこれらのヌルチェックを入れることは理にかなっていますか?たとえば、次のように事実上

if(object == null){ 
    log.error("...") 
    throw new SomeRuntimeException(""); 
} else{ 
    object.someMethod(); 
} 

、上記のコード部分は、文と同じですobject.someMethod();

以降で objectの値がnullの場合、例外は両方のケースでスローされていたであろう

(NullpointerExceptionが発生)。

NullpointerExcetion(NPE)をマスクしてカスタムRunTimeExceptionをスローするのは本当に意味がありますか(上記のスニペットのように)? 私はNPEを悪として扱っている開発者をいくつか見てきました。しばしば、それをマスクしてカスタム例外を隠すための防御方法を見つけようとしました。 このマスキングは本当に必要ですか?

質問

  1. は、それは我々がそのヌル状態から回復できない場合は、私たちのコードはNPEて失敗することを可能にすることは理にかなっていませんか? (上記の例では、回復不可能なシナリオです)
  2. そうでない場合、なぜですか?ポストされたあなたのようなケースでは
+1

あなたのコードがある場合は、あなただけが必要な場合、私はこの前に、あなたは決してnull要素を持っている必要がありWEEL-構築し、NPEチェックを^^使用しないpersonnally NEVERましたオブジェクトの作成を確実にするか、これを好きになる – azro

+0

これは興味深い質問ですが、私はそれが決定的ではあるが意見に基づいていない回答をどのように認めているかはわかりません。 –

+0

私は、 'null'でないと期待されるパラメータに対して' @ Nonnull'アノテーションを使う方が好きです。 '@ Nonnull'アノテーションはデフォルトでは利用できませんが、多くのIDE(intelliJなど)でサポートされています。あなたはあなたの依存関係に 'com.google.code.findbugs.annotations'を追加する必要があります。これにより、IDEは注釈を付けるメソッドに 'null 'を渡す機会があるかどうかなど、あなたに警告することができます。この時点で、あなたは「ヌル」を期待していないことを他人に理解させるのにも役立ちます。 – Philipp

答えて

8

、チェックしてもメリットはありません。あなたはRuntimeExceptionを別のものに置き換えます。これは余分な情報や値を持たないものです(そしておそらくより少なくてあなたのコードに慣れていない人には誰でもNPEが何であるか知っていて誰もがあなたのSomeRuntimeException )。私は明示的な検査を検討したい

メイン2回は、以下のとおりです。

  1. 私が代わりに未チェックのチェック例外をスローする場合。
  2. 実際に参照を使用する前にnullをチェックしたいとき。

2番目のケースは、あとで参照を保存する場合にのみ特に重要です(コンストラクタなど)。その場合、誰かが参照を使用してNPEをトリガーするときに、最初にヌルがどのようにそこに到達したかを見つけることは難しいかもしれません。フィールドに保存する直前にチェックすることで、根本的な原因を見つける良い機会になります。実際、これは一般的なパターンであり、JDKにもrequireNonNullヘルパーがあります。あなたは十分に確立、高評判のプロジェクトの多くを見れば

、私はあなたが「ちょうどそれを使用し、発生した場合NPEは身を任せる」パターンが一般的であることがわかりますね。私の頭の上から一例を取るためには、JDKのCollections.sortのコードはlistは、メソッドの引数である場合には、単にlist.sort(null)です。ヌルの場合、その行はNPEを投げます。

4

内部コードの場合、ヌルチェックの束はかなり役に立たない。期待していないメソッドにnullを渡しているのであれば、NPEで失敗させるだけで間違いを防ぐよりも容認できます。コードが制御しない他のコードから呼び出された場合は、メソッドの先頭にアサート(Objects.requireNonNull)するか、nullで渡す結果を示すJavadocを指定します。後者のアプローチは、JDKコードベースで広く使用されています。

3

NPEは、発生した問題に「意味」を与えないため、悪いと見なされます。 Javaアプリケーションのコードについては、NPEを投げる可能性があります。だから、それが起こったとき、あなたはNPEを引き起こす原因についての即座の手がかりを持っていません。プログラミングエラー?誤った外部依存関係ですか?そのため、考えられる原因のこの品種の

、それは問題に対処するために上位レベルでのNPEをキャッチするために非常に悪い習慣になり

だから、あなたは可能性が、例では、あなたが与えたように、時を持っている場合あなたがコードを書いているとき、あなたはobject == nullのときに何を意味するのかを知っている人です。したがって、意味的な意味を持つ例外を投げることを選択した場合、それを上位レベルで具体的にキャッチし、この特殊なケースを機能的に扱うことができます。他

(... == null)の場合は定型については、Java 8を使用してOptionals

0

場合...、あなたはそれを避けることができ、私は多くの人が頻繁に簡単な使用含む、個人クラスArgumentChecker.javaを書きましたcheckPositive(double value)、checkEquals(int v1、int v2)、checkNonDecreasingOrder(int ... args)、checkNonNull(Object obj)などの例外チェックのための静的メソッド。

public static void checkAllEqualsTo(int theValue, int... values){ 
    for (int i = 0; i < values.length; i++) { // StringUtils is also a personal simple class containing some wrapped methods 
     if (values[i] != theValue) 
      throw new IllegalStateException(NOT_ALL_EQUAL_EXCEPTION + "; values = " + StringUtils.toString(values, values.length) + ", theValue = " + theValue); 

    } 
} 

public static void checkAllEquals(int... values){ 
    if (values.length == 0){ 
     return; 
    } 
    checkAllEqualsTo(values[0], values); 
} 

これらのメソッドは再利用可能であり、この方法は、方法はまた、簡潔で読みやすいですチェックこれらの例外を呼び出します。この質問のために

は、コードは次のようになります。

ArgumentCheck.checkNonNull(object); 
object.someMethod(); 
関連する問題