Optional: nullを使わない
背景
クイックソートの考案者であるアントニー・ホーア(Antony Hoare)が 2009年の QCon London で null の発明は10億ドルにも相当する誤りであった と発言しています.
null
があると,NullPointerException
が発生する可能性があります.
そもそも null
を使わなければ,NullPointerException
が発生することはありません.
近年のプログラミング言語では,null
を許容しない変数を定義することも可能です.
例えば,Kotlin では,次のプログラムの1行目のように,デフォルトでは null
を代入するとコンパイルエラーとなります.
null
を代入するには,型名に ?
を付け,null許容型として扱う必要があります.
var str1: String = null; // コンパイルエラー
var str2: String? = null; // OK
Javaではnull
を許容しない変数は宣言できません.
その代わりに Optional
という型を利用します.
Optional
概要
Optional
とは,null
かもしれない値を扱うためのラッパ型です.
map
やifPresent
メソッドなどで値が存在するときのみに処理を実行できます.
作成
String someString = // 文字列を代入する.
Optional<String> optional = Optional.of(someString);
ただし,Optional.of
は null
を渡すと NullPointerException
が投げられます.
null
かもしれない変数をもとに Optional
型の変数を作成するには,ofNullable
を用います.
String nullString = null;
Optional<String> optional = Optional.ofNullable(nullString);
利用方法
あるディレクトリが保持するファイル・ディレクトリ一覧を取得する.
Optional
を利用しない場合
File fileOrDirectory = // ファイルもしくはディレクトリ
File[] entries = fileOrDirectory.listFiles();
if(entries != null) {
for(Integer i = 0; i < entries.length; i++) {
System.out.printf("%d: %s%n", i, entries[i].getName());
}
}
Optional
を利用する場合
File fileOrDirectory = // ファイルもしくはディレクトリ
Optional<File[]> entries = Optional.ofNullable(fileOrDirectory.listFiles());
// fileOrDirectory がファイルを指す場合,null が返される.
// https://docs.oracle.com/javase/jp/8/docs/api/java/io/File.html#listFiles--
entries.ifPresent(files -> { // entries の中身が null でない場合にのみ,下の for 文が実行される.
for(Integer i = 0; i < files.length; i++) { // files は entries の中身である File[] 型.
System.out.printf("%d: %s%n", i, entries[i].getName());
}
})
以上のものをもっと簡略化して書くと次のようになる.
File fileOrDirectory = // ファイルもしくはディレクトリ
Optional<File[]> entries = Optional.ofNullable(fileOrDirectory.listFiles());
entries.ifPresent(files -> IntStream.range(0, files.length)
.forEach(i -> System.out.printf("%d: %s%n", i, files[i])));
参考資料
- null安全でない言語は、もはやレガシー言語だ (qiita.com)
- なぜ null はそのプログラミング言語にあるのか(その1 - ”無”の無い世界) (qiita.com)
- 【Optional入門】Javaでnullを扱うベストプラクティスのご紹介 (www.bold.ne.jp)