57

事後条件がある場合、メソッドの戻り値は null であってはなりません。どうすればよいですか?

私はそれをできた

assert returnValue != null : "Not acceptable null value";

しかし、アサーションはオフにすることができます!

それでいいのか

if(returnValue==null)
      {
           throw new NullPointerException("return value is null at method AAA");
      }

?

または、そのような条件にはユーザー定義の例外 ( NullReturnValueException など) を使用する方がよいでしょうか?

4

19 に答える 19

71

自分で投げないことをお勧めNullPointerExceptionします。

Thorbjørn Ravn Andersen が以下のコメントで述べているように、これを行わない主な理由は、意図的にスローされた NPE と「本物の悪い NPE」を混ぜたくないからです。

したがって、「有効な」NPE を認識できると確信できるまでは、有効な引数値ではないIllegalArgumentExceptionことを API ユーザーに伝えたい場合に使用することをお勧めします。null不正な null パラメータが渡されたときのメソッドの動作を文書化する必要があります。

別の(より現代的な)オプションは@NotNull、引数の近くで注釈を使用することです。@NotNull アノテーションの使用に関する記事はこちらです。

先に述べたように、NPE を投げても自分やチームメイトが混乱しない場合もあります。NPE の原因は明確で認識可能でなければなりません。

たとえば、 のような前提条件モジュールを備えたライブラリを使用する場合、不正に渡された null を処理するには、のようなメソッドGuavaを使用することが望ましい方法であることがわかります。checkNotNull()

checkNotNull(arg, msg)Preconditions.checkNotNull()は NPE をスローしますが、スタックトレースから、これが生成されたものであり、未知のバグではなく、予想される動作であることは明らかです。

于 2010-07-23T23:06:40.740 に答える
44

JVMがNPEをスローする前に、できるだけ早くNPEをスローしても問題はないと思います-特にnull引数の場合。これについては議論があるようですが、Java SE ライブラリには、まさにこれを行う多くの例があります。NPE を自分で投げることができないという点で、なぜ NPE が神聖であるべきなのかわかりません。

しかし、私は脱線します。この質問は何か違うものについてです。戻り値がnullであってはならないという事後条件について話している。この場合、確かに null は、まさにメソッド内にバグがあることを意味しますか?

これをどのように文書化しますか?「戻り値が予期せず null の場合、このメソッドは NullPointerException をスローします」? これがどのように起こるかを説明せずに?いいえ、ここではアサーションを使用します。例外は、おそらく発生する可能性のあるエラーに対して使用する必要があります。メソッド内に何か問題がある場合に発生する可能性があることをカバーするのではなく、誰の役にも立たないからです。

于 2010-07-24T23:10:16.347 に答える
29

NullPointerExceptionこれがJavaで予期しないnull値を伝える慣用的な方法であることを考えるとNullPointerException、自家製のものではなく標準をスローすることをお勧めします。また、システム例外の種類が存在する場合に備えて、独自の例外の種類を作成しないことを、最小の驚きの原則が示唆していることにも注意してください。

アサーションはデバッグには適していますが、特定の条件を処理する必要がある場合には適していないため、エラー状態を処理する方法としてはあまり適していません。

于 2010-07-23T21:49:57.507 に答える
15

問題は、何かがnullかどうかを確認するのを忘れNullPointerExceptionたり、nullである間違った引数を与えたりするのを忘れたときに発生することです。

私の経験から、Java プログラマーは、この例外がコードのバグによって引き起こされていることをすぐに理解するので、手動で例外をスローすると、ほとんどのプログラマーにとって非常に混乱することになります。IllegalArgumentException受け入れられない引数 (null など、null であってはならないもの) を渡す場合は、これを使用することをお勧めします。

また、別のヒューリスティックもトリガーします。NPE = 誰かがここのコードでエラーを起こしました。IllegalArgumentException= メソッドに渡されたオブジェクトが無効です。

一方、javadoc には次のように記載されています。

アプリケーションは、このクラスのインスタンスをスロー
して、オブジェクトの他の不正使用を示す必要がありnullます。

したがって、NPE を投げることは合法ですが、一般的な方法ではないため、お勧めしIllegalArgumentExceptionます。

于 2013-03-22T16:04:50.903 に答える
8

確かに、NullPointerException のスローに対する普遍的な法則はありませんが、そのような抽象化された例で実際にスローすべきかどうかを回答するのは困難です。あなたがしたくないことは、NullPointerException をキャッチしようとする立場に人々を巻き込むことです。次のようなコード (実際の例、誓います):

catch (NullPointerException npe) {
  if (npe.getMessage().equals("Null return value from getProdByCode") {
    drawToUser("Unable to find a product for the product type code you entered");
  } 
}

あなたが何か間違ったことをしているという確実な指標です。したがって、null の戻り値が、実際に通信できるシステム状態の指標である場合は、その状態を通信する例外を使用します。ヌルポインターをチャックするためだけに参照をヌルチェックすることが理にかなっているケースはあまりありません。通常、コードの次の行は、nullpointer (またはより有益なもの) をチャックします!

于 2010-07-23T22:12:23.393 に答える
6

http://pmd.sourceforge.net/pmd-5.0.1/rules/java/strictexception.html
"NullPointerExceptions のスローは避けてください。ほとんどの人は仮想マシンがスローしたと想定するため、これらは混乱を招きます。代わりに IllegalArgumentException を使用することを検討してください。これは、明らかにプログラマーが開始した例外と見なされます。」

于 2013-03-22T15:31:19.020 に答える
5

説明を覚えていれば、NullPointerException の使用は問題ないと思います。それは、調査している人が扱っているものです (行番号が変わる可能性があります)。また、特別な場合にメソッドが null ポインター例外をスローすることを忘れないでください。

最初にメソッドのパラメーターを確認すると、 athrow new IllegalArgumentException("foo==null")も受け入れられます。

于 2010-07-23T23:00:18.393 に答える
4

戻り値を返せないメソッドコントラクトを記述する場合は、null必ず返さないようにした方がよいでしょうnull。しかし、これは NullPointerException ではありません。返さなければならない値がnull明らかに、呼び出し元が不正な引数を与えた ( IllegalArgumentException ) か、有効な状態にない ( IllegalStateException ) か、または NullPointerException 以外のより意味のある例外条件が発生した (通常はプログラミング エラー)。

于 2010-07-24T06:32:21.847 に答える
3

私がO'Reilly の Java in A Nutshellと呼んでいる専門家によって書かれた本には、NullPointerException のこの定義がリストされています。

フィールドへのアクセスまたは null オブジェクトのメソッドの呼び出しの試行を通知します。

null を返すことはそのどちらでもないので、独自の例外を作成する方が適切だと思います。

于 2010-07-23T21:51:08.773 に答える
3

NullPointerExceptionのJavaDoc には次のように記載されています。

オブジェクトが必要な場合に、アプリケーションが null を使用しようとするとスローされます。これらには以下が含まれます:

* Calling the instance method of a null object.
* Accessing or modifying the field of a null object.
* Taking the length of null as if it were an array.
* Accessing or modifying the slots of null as if it were an array.
* Throwing null as if it were a Throwable value. 

アプリケーションは、このクラスのインスタンスをスローして、null オブジェクトの他の不正な使用を示す必要があります。

事後条件に違反することは違法行為だと考えています。ただし、使用する例外はそれほど重要ではないと思います。これは、到達できないはずの (そしてうまくいけば到達できない) コードパスについて話しているため、その例外に固有のエラー処理がなく、したがって唯一の効果その名前は、ログ ファイル内のエントリの別の表現であり、誰も見ることはありません。

対照的に、事後条件に違反する可能性が高いと思われる場合は、メソッドが呼び出された引数など、デバッグ情報をさらに含めることをお勧めします。

于 2010-07-23T22:03:50.533 に答える
2

はいぜったいに。

JDK7でもこれを解決します。オブジェクト#requireNonNullを参照してください

void doWith(final Object mustBeNotNull) {

    /*
    // bush style
    if (mustBeNotNull == null) {
        throw new IllegalArgumentException("mustBeNotNull must not be null");
    }
    */

    /*
    // obama style
    if (mustBeNotNull == null) {
        throw new NullPointerException("mustBeNotNull must not be null");
    }
    */

    // kangnam style
    Objects.requireNonNull(mustBeNotNull, "mustBeNotNull must not be null");

    assert mustBeNotNull != null;
}
于 2013-02-08T06:04:24.133 に答える
1

多くの場合、ロジックが深くなりすぎて、呼び出し元のプログラマーが何が null であるかを理解するのに苦労する前に、NPE をスローすることをお勧めします。addListener() メソッドが良い例です。

知らされていない反対票にもかかわらず、JDKにはまさにこれを行う多くのメソッドがあります。

于 2010-07-24T10:34:18.050 に答える
1

NullPointerException を手動でスローしないでください。呼び出しルーチンは、説明を確認しないと、実際の NullPointerException か手動の NullPointerException かを判断できません。この場合、呼び出し元のメソッドがこの例外から正しく回復できるように、問題に一致する独自の例外をロールバックする必要があるようです。おそらく、PostConditionException は多くの状況で十分に汎用的です。

于 2010-07-23T23:21:39.473 に答える
0

Java-verse では、オブジェクトを期待する場合、null は常に有効な値です。このような不可能な投稿条件は避けたほうがよいでしょう。本当にnullを守れない場合は、プリミティブを返すことができるようにメソッドを作り直す必要があります。

于 2010-07-24T07:47:48.850 に答える
-1

その例外をスローすることは、場合によっては良い習慣ではありません.ifステートメントですでにキャッチしているのに、なぜだろうか?

if(戻り値==null)

于 2010-07-24T01:53:47.983 に答える