Optionalクラス
Optionalクラス(java.utilパッケージ)は、nullチェックを簡単化し、NullPointerExceptionの発生を未然に防ぐためのクラスです。
たとえば以下は、メンバー情報をMapで管理するUtilMemberListクラスと、これを利用するためのサンプルです。まずは、Optionalクラスを利用せずに記述してみます。
UtilMemberList.java
package com.example.mynavi.util; import java.util.Map; public class UtilMemberList { // メンバー情報を「id: 名前」の形式で管理 public Map<String, String> list; public UtilMemberList(Map<String, String> list) { this.list = list; } // id値をキーにメンバーの名前を取得 public String getNameById(String id) { return this.list.get(id); } }
UtilOptBasic.java
package com.example.mynavi.util; import java.util.Map; import java.util.Optional; public class UtilOptBasic { UtilMemberList ml = new UtilMemberList(Map.of( "N-001-0A", "佐藤敏夫", "F-023-0B", "田中修", "A-104-0C", "鈴木直男" )); String name = ml.getNameById("Z-9999-0X"); System.out.println(name.trim()); } }
Map#getメソッドは、指定されたキーが存在しない場合にnullを返します。その場合に、trimメソッドをそのまま呼び出してしまうと、NullPointerException例外の原因となるわけです。
これを避けるために、Optionalクラス以前では、以下のようなnullチェックを施すのが一般的でした。
if(name == null) { System.out.println("存在しません。"); } else { System.out.println(name.trim()); }
しかし、呼び出し側では戻り値にnullの可能性があるかどうかを考慮しながらコードを記述しなければならないため、漏れの原因となります。そこでOptionalクラスを利用して、getNameByIdメソッドを書き換えます。
import java.util.Optional; ...中略... public Optional<String> getNameById(String id) { return Optional.ofNullable(this.list.get(id)); }
Optional.ofNullableは、与えられた値をもとにOptional<String>オブジェクトを生成します。Optional<String>は、nullであるかもしれないStringを意味します。これを読み取るのが以下のコードです。
import java.util.Optional; ...中略... Optional<String> name = ml.getNameById("Z-9999-0X"); System.out.println(name.orElse("存在しません。").trim());
Optional<String>オブジェクトから値を取得するには、orElseメソッドを利用します。引数は値がnullの場合に採用するデフォルト値を意味します。先ほどのifによる分岐に比べると、コードがシンプルになっていますし、なによりOptionalクラスのままでは値を利用できないので、nullチェックが強制されます。null値の可能性がある戻り値では、このようにOptionalクラスでラップすることでnull安全なコードを記述できます。