Optional.ofNullableではなくOptional.ofを使用する理由


232

Java 8 Optionalクラスを使用する場合、オプションで値をラップする方法は2つあります。

String foobar = <value or null>;
Optional.of(foobar);         // May throw NullPointerException
Optional.ofNullable(foobar); // Safe from NullPointerException

Optional.ofNullable使用する唯一の安全な方法は理解できるが、OptionalなぜOptional.of存在するのか。Optional.ofNullable 常に使用して、常に安全な側にいませんか?


1
これを使用するにはどのパッケージをインポートする必要があるか教えてください。
LoveToCode

4
@LoveToCode java.util.Optional-あなたはJDK 8以降を使用している場合、それが利用可能です
whirlwin

11
彼らが持っているならば、私は大好きだofNullable()という名前of()ととof()命名ofNotNull()
ロバート・ニーストロージを


「なぜOptional.ofが存在するのですか?単にOptional.ofNullableを使用し、常に安全側にいるのはなぜですか?」ユーザーの必要なデータが存在しない場合、例外をスローする必要があるとしましょう。したがって、それは完全にユースケースに依存します。baeldung.com/java-optional-throw-exception
Karan Arora

回答:


306

あなたの質問は、スローNullPointerExceptionする可能性のあるコードがそうでない可能性のあるコードよりも悪いという仮定に基づいています。この仮定は間違っています。foobarプログラムロジックが原因でnullになることはないと予想さOptional.of(foobar)れる場合はNullPointerException、プログラムにバグがあることを示すが表示されるので、使用する方がはるかに適切です。あなたが使用している場合Optional.ofNullable(foobar)foobarであることを起こるnullバグのため、そしてあなたのプログラムは黙っ大きな災害とすることができる、誤っていきます。この方法では、エラーがずっと後に発生する可能性があり、どの時点でエラーが発生したのかを理解するのがはるかに困難になります。


129
" プログラムロジックのためにfoobarがnullになることはないと予想される場合は、Optional.of(foobar) " を使用することをお勧めします。これは少し奇妙に思えます-値がnullいずれの場合もないことがわかっている場合は、値の中にラップするのではなく、値自体を使用しないのはなぜOptionalですか?
Konstantin Yovkov

54
@kocko、Optional実装しているインターフェースの要求に応じて、メソッドからを返す必要がある場合があります(おそらく他の実装者が空のオプションを返す場合があります)。または、オプションのコレクション/ストリームを作成したい場合、nullでないことが保証されているものとそうでないものがあります。または、いくつかのブランチでオプションを作成する条件付きロジックがあり、単一のブランチでそれがnullでないことは確かです。
Tagir Valeev、2015

28
オプションとは、存在する場合と存在しない場合があることを意味します。存在しない!= null。nullこの場合、「foobarが存在することを期待していますが、バグのためnullです」という意味です。Optional.isPresent() == falsefoob​​arが存在しないことを意味します。つまり、これは予想される正当な動作です。
Buurman、2015

43
@kocko:簡単な例:含まれていませんに期待されている値を...return list.isEmpty()? Optional.empty(): Optional.of(list.get(0));listnull
ホルガー

5
@Harishあなたが私に尋ねているなら、私はどこでもOptionalsを使うことを勧めません。それは別の質問です。ここでいくつかの意見を確認できます
Tagir Valeev 2016年

12

さらに、オブジェクトがnullの場合にコードが機能しないことがわかっている場合は、次を使用して例外をスローできます。 Optional.orElseThrow

String nullName = null;
String name = Optional.ofNullable(nullName).orElseThrow(NullPointerException::new);

1
しかし、これにはさらに短い時間を使用できますString name = Objects.requireNonNull(nullName);
Holger

1
良い点は@Holgerですが、.orElse()メソッドでは、制御フローまたは情報ロギングの処理を改善するのに役立つカスタム例外を使用できます。
Nikos Stais

1
まあ、あなたは追加情報を与えるために例外のメッセージを提供することができます。NullPointerException問題が明らかにリファレンスではnullない場合とは異なる例外を使用するなど、他のカスタマイズの試みは、間違った方向へのステップになります。
Holger、

また、あなたはより具体的な(例えばカスタム)例外をスローするようにオプションを使用することができ、ないNPEは、NPEがあまりにも一般的なもので、あなたのような何かを投げることができるnew NullNameException("meaningful msg")
デイブ

1

これはシナリオによって異なります。

いくつかのビジネス機能があり、その価値を持つ何かをさらに処理する必要があるがnull、処理時に価値があるとそれに影響を与えるとしましょう。

その後、その場合はを使用できますOptional<?>

String nullName = null;

String name = Optional.ofNullable(nullName)
                      .map(<doSomething>)
                      .orElse("Default value in case of null");

0

いずれにしても、オプションは主にサービスの結果に使用する必要があります。サービスでは、手元にあるものを知っており、結果がある場合はOptional.of(someValue)を返し、結果がない場合はOptional.empty()を返します。この場合、一部の値がnullになることはありませんが、それでもOptionalを返します。


1
Sumeshの編集に感謝しますが、最後の行の「someValue」は「some Value」に編集され、上記の「Optional.of(someValue)」の変数を参照しているため、someValueのままである必要があると思います。
espendennis
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.