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かもしれない値を扱うためのラッパ型です. mapifPresentメソッドなどで値が存在するときのみに処理を実行できます.

作成

String someString = // 文字列を代入する.
Optional<String> optional = Optional.of(someString);

ただし,Optional.ofnullを渡すと 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])));

参考資料