nullを扱う新たな方法として
JavaSE8からOptionalというクラスが
java.utilパッケージに加わった。
(他の言語ではすでにあった)

Javaではnullのオブジェクトに対して、
フィールドの参照やメソッドの呼び出しを行うと
すぐにNullPointerExceptionになってしまう。

なのでnullの扱いには注意が必要で、
nullをうまく扱えるかが初心者との境目だったりもする。

普通にnullチェックをしたり、NullObjectを作ってみたり
という方法があるが、Optionalはこれらとはまた違う方法。

慣れないと何がいいのかピンとこないが、
なるべくわかりやすくOptionalの良さをまとめる。

Optionalがnullを安全に扱う仕組み

Optionalは対象となるオブジェクトを保持する(だけ)。
JavaDocにも「コンテナ・オブジェクト」と書かれている。

Optionalクラス図

保持したオブジェクトを取得・利用する場合は、
必ずメソッドを介する。

そのメソッドは保持したオブジェクトがnullであっても
セーフティ(安全)な設計になっている。(get()を除く)

また、Optional自体はNullObjectになっているので
nullになることがない(させない)。
値が未定の場合でもOptional.empty()を割り当てればよい。

このように、

  • 対象となるオブジェクトがnullでもメソッドを介すので、安全
  • Optional自体もnullになることがないので、安全

ということで、Optionalはnullを安全に扱うことができる。

Optionalがnullを安全に扱う例
String value = null;
Optional<String> optionalValue = Optional.ofNullable(value);
String displayValue = optionalValue.orElse("(デフォルト)");
 
// 「(デフォルト)」と表示
System.out.println(displayValue);

vs NullObject

仕組みとしては上記の通りだが、
ほかの方法(NullObject)と比べてみる。

nullを扱う工夫された方法として、
NullObjectという方法(パターン)がある。

それはそれでよいが、
Optionalは「NullObjectを定義しなくてもいい」
という点で優れている。

NullObjectでは一番最小の実装であっても、
オブジェクトの生成やファクトリメソッドは必要。

1,2個であれば何ら問題ないが、
いくつもあると面倒。

その点で言うとOptionalは、
新たにコードを実装する必要がない。

また、nullのときのメソッドの挙動も問題があれば
オーバーライドしなくてはいけない。

一方Optionalは、
nullのときの挙動もそのオブジェクトを利用する人が決めることになるので
使う人がその状況で決めればいい。

Optional自体がNullObjectであるということからもわかるように
OptionalとNullObjectでは活躍の舞台が微妙に違うかもしれない。

ただ、nullを扱うという点では
NullObjectよりも手間がかからないのは
明らかなことがわかる。

フィールドにもメソッドの引数・戻り値にもOptionalを使う

仕組みや良さはこんなところ。
ではどのように使っていくかになるが、
意味的にnullがある可能性があればどこでも使える。

例えば、次のようなフィールドなどである。

public class Person {
    String name;
    String mailAddress;
    Optional<String> twitterAccount;
}

この例では、
Personは名前とメールアドレスは必ずあるが
ツイッターアカウントはあるかどうかわからないので
Optionalとしている。

Optionalとしていることで、
必須項目ではないことが伝わる。

他にもメソッドの引数、戻り値なども利用できる。

public interface PersonDao {
 
    Optional<Person> find(String name);
 
}

Daoなんかでもよく、
結果オブジェクトを必ず取得できるか否かの挙動で
迷うことがある。

そんなことで迷うよりも
Optionalにしてクライアント側で
挙動を決めさせればよい。

このようにあらゆるところで、
Optionalは利用できる。

あとは使い慣れるだけ

これまでの説明のとおり、
Optionalは直接nullチェックやNullObjectよりも
スマートに扱える。

問題はOptionalのスタイルになれるのに
時間が必要なこと。

Javaでは相当後発になるので
サンプルが少ない。

ただ、慣れてくると無くてはならないものになる。

lomokの@NonNullなどと併用していけば
「nullを渡さない、返さない、保持しないといったこと」が
スマートに徹底できる。

nullを使いたくなったら、Optionalを思い浮かべて欲しい。

PR