Oracle JDKの多くのJava 8メソッドがObjects.requireNonNull()
を使用していることに気付きました。与えられたオブジェクト(引数)がNullPointerException
であれば、内部的にnull
をスローします。
public static <T> T requireNonNull(T obj) {
if (obj == null)
throw new NullPointerException();
return obj;
}
しかしNullPointerException
オブジェクトが間接参照されている場合は、null
がスローされます。それで、なぜこの余分なnullチェックをしてNullPointerException
を投げるべきなのでしょうか。
1つの明白な答え(または利点)は、それがコードを読みやすくするということです、そして私は同意します。メソッドの冒頭でObjects.requireNonNull()
を使用する他の理由を知りたがっています。
そうすることで、を明示的にすることができるからです。好きです:
public class Foo {
private final Bar bar;
public Foo(Bar bar) {
Objects.requireNonNull(bar, "bar must not be null");
this.bar = bar;
}
またはもっと短い:
this.bar = Objects.requireNonNull(bar, "bar must not be null");
これであなたは知っている:
new()
を使って作成されたときこれと比較してみましょう。今日はFooオブジェクトを作成し、明日明日にそのフィールドを使用してスローするメソッドを呼び出します。おそらく、その参照がコンストラクタに渡されたときにその参照がnull昨日だったのは、明日はわかりません。
つまり、このメソッドを明示的に使用してincomingreferenceをチェックすることで、例外が発生した時点を制御することができます。スローされます。そしてたいていの場合、はできるだけ速く失敗したいと思います!
主な利点は以下のとおりです。
bar
がnullではないと安全に仮定することができるからです - そしてそれ故あなたは他の場所でif (bar == null)
チェックを必要としません!コードはできるだけ早くクラッシュするはずです。作業の半分を実行してからnullを参照解除し、クラッシュした後でシステムを無効な状態にすることがあります。
これは一般的に「早期に失敗する」または 「高速で失敗する」 と呼ばれます。
しかし、nullオブジェクトが間接参照されると、NullPointerExceptionがスローされます。それで、なぜ、この余分なnullチェックをしてNullPointerExceptionを投げるべきなのでしょうか。
つまり、問題を即座におよび確実に検出します。
検討してください:
.NETは、NullReferenceException
からArgumentNullException
( "null値を間接参照しました")を分離することでこれを改善します( "nullとして引数として渡すべきではありませんでした - そしてthis私はJavaが同じことをしたかったのですが、たとえNullPointerException
があっても、エラーが可能な限り早い時点で投げられるならコードを直すことはずっと簡単です検出されます。
メソッド内の最初のステートメントとしてrequireNonNull()
を使用すると、今すぐ例外の原因を特定することができます。
スタックトレースは、メソッドの入力直後に例外がスローされたことを明確に示しています 呼び出し元がその要件/契約を尊重していないためnull
オブジェクトを別のメソッドに渡すと、実際には一度に例外が発生しますが、null
オブジェクトに対する特定の呼び出しで例外がスローされるため、問題の原因を理解するのが複雑になる場合があります。
ちなみに、Object#requireNotNull
がいくつかのjreクラス自体の中でJava-9の前に実装される前にわずかに異なる前に、これは速く失敗します。ケースを仮定します:
Consumer<String> consumer = System.out::println;
Java-8ではこれは次のようにコンパイルされます(関連する部分のみ)
getstatic Field Java/lang/System.out
invokevirtual Java/lang/Object.getClass
基本的にはyourReference.getClass
のような操作 - yourRefercenceがnull
の場合は失敗します。
Jdk-9では、同じコードがコンパイルされるのと同じように状況が変わりました。
getstatic Field Java/lang/System.out
invokestatic Java/util/Objects.requireNonNull
あるいは基本的にObjects.requireNotNull (yourReference)
基本的な使用法は、NullPointerException
をすぐにチェックしてスローすることです。
同じ要件を満たすためのもう1つの優れた代替手段(ショートカット)は、 @ NonNull lombokによる注釈です。