Java8 から null のハンドリングに新しく Optional というものが使えるようになった。
簡単に言うと、Optional は単なる箱で内部に null を内包している可能性があることを示すものである。 つまり null が戻されるという可能性をシグネチャとして明示するためのマーカーである。
そして null の処理に関しては定番の動きがあるので、それもまとめて面倒見ちゃおうという便利メソッドが実装されているというわけ。
null が戻らない仕様ならば、Optional を使う必要は無い。
null 内包版
Optional<String> hoge = Optional.empty();
インスタンス内包版
Optional<String> hoge = Optional.of("ほげ");
実行時までどっちかわからない版
Optional<String> hoge = Optional.ofNullable(hoge);
Optional<String> hoge = Optional.of("ほげ"); String s = hoge.get(); hoge = Optional.empty(); s = hoge.get(); // 例外発生 NoSuchElementException
NoSuchElementException は非チェック例外
Optional<String> hoge = Optional.empty(); System.out.println(hoge.isPresent()); //=> false; hoge = Optional.of("ほげ"); System.out.println(hoge.isPresent()); //=> true;
null を内包している状態での get は例外発生なので、get 前に必ずこの処理を入れる必要がある。
これで null チェックして再代入という定番の記述が1行で書ける
固定値版
Optional<String> hoge = Optional.empty(); String s = hoge.orEles("piyo"); // piyo
Getter版 パラメータに Getter的なラムダを取ることができ、それにより null 値の場合の代替値を決定できる
Optional<String> hoge = Optional.empty(); String s = hoge.orElesGet(()->{"piyo"}); // piyo
当然どちらも、値が入っていればそれが返る。
null の場合に独自例外を発生させたいとう場合もあるので、このように書ける
Optional<String> hoge = Optional.empty(); String s = hoge.orElesThrow(HogeHogeException::new);
判定して何か処理するのをラムダで一発で書けるようになっている。
Optional<String> hoge = Optional.of("ほげ"); hoge.ifPresent((e)->{ System.out.println(e); });
ifPresent 自体の戻りは void になっていて、さらに Java のラムダは JS のクロージャのようにスコープを内部に持ち込むことができないので、 ここでの内部処理結果は、そのインスタンスを通じてしか外部に持ち出すことができない。 なので、この処理は副作用専用、もしくは加工専用となる。