1. ホーム

[解決済み】オプショナルの使用方法

2022-03-26 19:04:22

質問

Java 8を使い始めてから6ヶ月ほど経ちますが、新しいAPIの変更にはかなり満足しています。まだ自信がないことの一つは、いつ Optional . 私は、何かというとどこでも使いたいような気がします。 null とか、まったくないとか。

これを使える場面はたくさんありそうですが、それが利点(可読性/ヌル安全性)をもたらすのか、それともさらなるオーバーヘッドを引き起こすだけなのか、よくわかりません。

そこで、いくつかの例を挙げてみました。 Optional は有益です。

1 - パブリックメソッドの戻り値として、そのメソッドが返す可能性がある場合 null :

public Optional<Foo> findFoo(String id);

2 - メソッドパラメータとして、パラメータが null :

public Foo doSomething(String id, Optional<Bar> barOptional);

3 - Beanのオプションメンバーとして。

public class Book {

  private List<Pages> pages;
  private Optional<Index> index;

}

4 - イン Collections :

一般的にはないと思います。

List<Optional<Foo>>

は何かを追加します - 特に filter() を削除するために null の値などですが、何か良い使い道はないでしょうか? Optional をコレクションで使用することはできますか?

見落としているケースがあれば教えてください。

解決方法は?

の主なデザイン目標は Optional は、値を返す関数が戻り値がないことを示すための手段を提供することである。参照 本論 . これにより、呼び出し元は流暢なメソッド呼び出しの連鎖を継続することができます。

これは、次のようなケースに最も近いと言えます。 #1 の質問で ですが。 値なし よりも、より正確な表現です。 ヌル のようなものなので IntStream.findFirst がNULLを返すことはあり得ません。


ユースケース #2 メソッドにオプションの引数を渡せば、うまくいくかもしれませんが、かなり不格好です。例えば、文字列とそれに続くオプションの2番目の文字列を受け取るメソッドがあるとします。このとき Optional を2番目の引数として指定すると、次のようなコードになります。

foo("bar", Optional.of("baz"));
foo("bar", Optional.empty());

nullを受け入れても、もっと素敵です。

foo("bar", "baz");
foo("bar", null);

おそらく最良の方法は、1つの文字列引数を受け入れ、2番目の引数にデフォルトを提供するオーバーロードされたメソッドを持つことでしょう。

foo("bar", "baz");
foo("bar");

これには制限がありますが、上記のいずれよりもはるかに素晴らしいものです。

使用例 #3 #4 を持つことで Optional をクラスフィールドやデータ構造で使用することは、API の誤用とみなされます。第一に、これは Optional にあるとおりです。第二に、それは何の付加価値ももたらさない。

の値がない場合の対処法は3つあります。 Optional 代替値を提供する、代替値を提供する関数を呼び出す、例外を発生させる、などです。フィールドに値を格納する場合は、初期化時または代入時に行います。OPが言及したように、リストに値を追加する場合、単に値を追加しないことで、存在しない値を平坦化することもできます。

を本当に格納したい場合、誰かが何らかの作為的なケースを思いつくと思います。 Optional をフィールドやコレクションで使用することはできますが、一般的にはこのようなことは避けた方がよいでしょう。