Java java.util パッケージの Optional クラス

Optional は Java 8 で追加されたクラスである。Optional クラスは null を扱うときに便利なクラスなので、基本的な書き方を見ていこう。

Optional とは

Optional は、メソッドの戻り値として null を返す可能性があることを明示したいときに使用する。メソッドが null を返す可能性があることを示すことで、そのメソッドを使用するプログラムをより安全に実装できるようにする。

Optional の宣言方法

Optional を使用するには、型をラップして使用する。

Optional<String> optional;

ユーザーが作成したクラスでも使用できる。

import java.math.BigDecimal;

public class Foo {
    private String str;
    private BigDecimal value;
}
Optional<Foo> opt;

Optional インスタンスの生成

Optional クラスはインスタンス生成用の static メソッドを提供しているため、このメソッドを使用して生成する。

  • Optional.empty() : 値が null の Optional インスタンスを生成する。
  • Optional.of(値) : 引数の値に対する Optional インスタンスを生成する。
  • Optional.ofNullable(値) : 引数の値が null の場合は empty、null でない場合は of メソッドの結果と同じである。

Optional.of は次のように宣言できる。

Optional<String> opt1 = Optional.of("test");

Optional.of では、引数が null の場合に java.lang.NullPointerException が発生するため注意が必要である。

Optional<String> opt1 = Optional.of(null);

そのため、主に Optional.ofNullable を使用する。

Optional<String> opt1 = Optional.ofNullable("test");
Optional<String> opt2 = Optional.ofNullable(null);

Foo test = new Foo();
Optional<Foo> opt3 = Optional.ofNullable(test);

Optional 戻り値メソッドの使用方法

Optional の戻り値メソッドについて見ていこう。

or メソッドの使用方法

or メソッドは、Optional.ofNullable メソッドの引数として指定されたオブジェクトが null の場合にのみ処理を実行する。

import java.util.Optional;

public class Sample {
    public static void main(String[] args) {
        String str = null;
        Optional<String> value = Optional.ofNullable(str);
        System.out.println(value.or(() -> Optional.of("null입니다.")).get());
    }
}

実行結果:

null입니다.

orElse メソッドの使用方法

Optional.ofNullable メソッドの引数が null の場合、orElse メソッドの引数の値を返す。null でない場合は、null でない値を返す。

import java.util.Optional;

public class Sample {
    public static void main(String[] args) {
        String str = null;
        Optional<String> value = Optional.ofNullable(str);
        str = value.orElse("null입니다.");
        System.out.println(str);
    }
}

実行結果:

null입니다.

orElseGet メソッドの使用方法

Optional.ofNullable メソッドの引数が null の場合、orElseGet メソッドの supplier の結果を返す。null でない場合は、null でない値を返す。

import java.util.Optional;

public class Sample {
    public static void main(String[] args) {
        String str = null;
        Optional<String> value = Optional.ofNullable(str);
        str = value.orElseGet(Sample::getDefaultValue);
        System.out.println(str);
    }
    
    private static String getDefaultValue(){
        return "Default 입니다.";
    }
}

実行結果は次のとおりである。

Default 입니다.

orElseThrow メソッドの使用方法

orElseThrow メソッドは、引数の有無によって処理が異なる。引数がない場合、値が null なら NoSuchElementExceptionthrow し、null でない場合は値を返す。

import java.util.NoSuchElementException;
import java.util.Optional;

public class Sample {
    public static void main(String[] args) {
        String str = null;
        Optional<String> value = Optional.ofNullable(str);
        try {
            str = value.orElseThrow();
            System.out.println(str);
        } catch (NoSuchElementException ex) {
            System.out.println("null입니다.");
        }
    }
}

実行結果:

null입니다.

引数がある場合は、throw を通じて例外クラスのオブジェクトを指定できる。

import java.util.Optional;

public class Sample {
    public static void main(String[] args) {
        String str = null;
        Optional<String> value = Optional.ofNullable(str);
        try {
            System.out.println(value.orElseThrow(() -> new RuntimeException()));
        } catch (RuntimeException e) {
            System.out.println("null입니다.");
        }    
    }
}

実行結果:

null입니다.

ifPresent メソッドの使用方法

null でない場合にのみ、引数に指定された処理を実行する。

import java.util.Optional;

public class Sample {
    public static void main(String[] args) {
        String str = null;
        Optional<String> value = Optional.ofNullable(str);
        value.ifPresent(System.out::println);
    }
}

これを実行すると、strnull なので何も処理されない。

ifPresentOrElse メソッドの使用方法

null の場合にも処理できる。null でない場合の処理を最初の引数に指定し、null の場合の処理を 2 番目の引数に指定する。

import java.util.Optional;

public class Sample {
    public static void main(String[] args) {
        String str = null;
        Optional<String> value = Optional.ofNullable(str);
        value.ifPresentOrElse(
            System.out::println, 
            () -> System.out.println("null입니다"));
    }
}

実行結果:

null입니다.