変数に値が代入されているかどうかを調べるためのイディオムとしてnullチェックがあります。
nullチェックがよく使用されるのが、メソッドの返り値や引数です。例えば、条件に合致した要素を探すsearchメソッドを考えてみましょう。ここでは、searchメソッドの返り値の型がResultクラスだとします(リスト1)。
リスト1●nullチェックの例
Result result = search(t -> t.startsWith("a"));
if (result == null) {
// 結果がなかった場合の処理
} else {
// 結果に応じた通常の処理
}
もし、条件に合致する要素がなければsearchメソッドはnullを返します。しかし、nullをそのまま扱ってしまうと、NullPointerException例外が発生してしまいます。
そこで、それを防ぐためにif文で変数の値がnullかどうかを調べるわけです。
しかし、nullチェックは本来の行いたい処理とは関係ありません。このため、nullチェックが多いと、コードから本来の処理を読み取ることが難しくなってしまいます。もちろん、何度もnullチェックを書かなければいけないので、記述も煩雑になります。
また、if文があるということは、コードの複雑度も増加することを意味しています。例えば、ユニットテストを記述するにも、if文の条件に合致したケースと合致しないケースの両方のテストを記述しなくてはいけません。
できれば、このようなnullチェックは書きたくないというのが本音ではないでしょうか。そこで、Java SE 8で導入されたのがjava.util.Optionalクラスです。
Project Lambdaの最終回となる今回は、このOptionalクラスを紹介していきます。
Optionalクラスとは
Optionalクラスは端的には、値を1つしか持つことのできないコンテナクラスです。そして、保持できる値はオブジェクト生成時に指定し、その後変更することはできません。つまり、イミュータブルなコンテナクラスということができます。
保持する値の型はジェネリクスの型パラメーターで指定します。
なお、ジェネリクスを使用するため、Optionalクラスでプリミティブ型の値を保持することはできません。その代りに、プリミティブ型に対応したOptionalIntクラス、OptionalLongクラス、OptionalDoubleクラスが提供されています。それぞれ、int型、long型、double型に対応しています。