web-dev-qa-db-ja.com

ヌルチェックvsオプションは存在チェック

誰かがOptionalNullPointerExceptionを回避するのにどのように役立つか説明できますか?

Optional<String> op = someFunc()
if(op.isPresent()) {
   op.get();
}
String possibleNull = op.get();

このコードはNullPointerExceptionにもなりやすいのではないですか?もしそうなら、なぜこのコードが優先されるのですか?

String op = someFunc()
if(op != null) {
   op.get();
}
String possibleNull = op;

関数が実際に戻り値を持っているかどうかを知るのに役立つという事実以外に、Optionalはどのような利点を提供しますか

17
Faiz Halde

関数から返された文字列を取得し、それを大文字に変換して出力したいとします。あなたが持っている場合:

String someFunc() { ... }

あなたは書きたくなるかもしれません:

System.out.println(someFunc().toUpperCase());

もちろん、これはNullPointerExceptionsomeFuncを返した場合にnullをスローします。代わりに、次のように仮定します。

Optional<String> someFunc() { ... }

その後

System.out.println(someFunc().toUpperCase());

OptionalにはtoUpperCaseメソッドがないため、機能しません。この時点で-うまくいけば-Optionalに直面するでしょう。これにより、Optionalが空の場合について考えるようになります。これは、NPEを回避するのに役立ちますが、おそらく多少だけです。

Optionalから値を取得する方法に焦点を当てているかもしれませんが、空のケースを忘れているかもしれません。ああ、getメソッドがあります:

System.out.println(someFunc().get().toUpperCase());

これは、例外がNoSuchElementExceptionであることを除いて、NPEと同じ問題を引き起こします。したがって、getに対してOptionalを盲目的に呼び出すと、nullかどうかを確認せずに参照でメソッドを呼び出すのとほとんど同じです。

(このため、 Brian GoetzOptional.getをJava 8.の最大の間違いであると考えています。8。Angelika Langerのインタビューを参照してください JAX 2015 Fragen und Antworten zu Java 8 約16分。最大かどうかはわかりませんが、間違いです。人々はgetが例外をスローすることを期待していません。)

Null参照または空のオプションのチェックに熱心である場合、

Optional<String> os = someFunc();
if (os.isPresent()) {
    System.out.println(os.get().toUpperCase());
}

古いものほど良いものはほとんどありません

String s = someFunc();
if (s != null) {
    System.out.println(s.toUpperCase());
}

Optionalrealの利点は、空のケースを安全に処理するためのかなり豊富なAPIを備えたライブラリクラスであることです。 。 Optionalを最初に返したメソッドへのカップルメソッド呼び出しをチェーンすることにより、Optionalに含まれている可能性のある値を処理できることがよくあります。たとえば、上記のサンプルを次のように書き換えることができます。

someFunc().map(String::toUpperCase)
          .ifPresent(System.out::println);
30
Stuart Marks