注目記事

【Javaコード入門】ユーティリティ_⑥Optionalクラス

Optionalクラス(java.utilパッケージ)は、nullチェックを簡単化し、NullPointerExceptionの発生を未然に防ぐためのクラスです。

たとえば以下は、メンバー情報をMapで管理するUtilMemberListクラスと、これを利用するためのサンプルです。まずは、Optionalクラスを利用せずに記述してみます。

UtilMemberList.java
  1. package com.example.mynavi.util;
  2.  
  3. import java.util.Map;
  4.  
  5. public class UtilMemberList {
  6.   // メンバー情報を「id: 名前」の形式で管理
  7.   public Map<String, String> list;
  8.  
  9.   public UtilMemberList(Map<String, String> list) {
  10.     this.list = list;
  11.   }
  12.  
  13.   // id値をキーにメンバーの名前を取得
  14.   public String getNameById(String id) {
  15.     return this.list.get(id);
  16.   }
  17. }
UtilOptBasic.java
  1. package com.example.mynavi.util;
  2.  
  3. import java.util.Map;
  4. import java.util.Optional;
  5.  
  6. public class UtilOptBasic {
  7.     var ml = new UtilMemberList(Map.of(
  8.       "N-001-0A", "佐藤敏夫",
  9.       "F-023-0B", "田中修",
  10.       "A-104-0C", "鈴木直男"
  11.     ));
  12.  
  13.     var name = ml.getNameById("Z-9999-0X");
  14.     System.out.println(name.trim());
  15.   }
  16. }

Map#getメソッドは、指定されたキーが存在しない場合にnullを返します。その場合に、trimメソッドをそのまま呼び出してしまうと、NullPointerException例外の原因となるわけです。

これを避けるために、Optionalクラス以前では、以下のようなnullチェックを施すのが一般的でした。

  1. if(name == null) {
  2.   System.out.println("存在しません。");
  3. } else {
  4.   System.out.println(name.trim());
  5. }

しかし、呼び出し側では戻り値にnullの可能性があるかどうかを考慮しながらコードを記述しなければならないため、漏れの原因となります。そこでOptionalクラスを利用して、getNameByIdメソッドを書き換えます。

  1. import java.util.Optional;
  2. ...中略...
  3. public Optional<String> getNameById(String id) {
  4.   return Optional.ofNullable(this.list.get(id));
  5. }

Optional.ofNullableは、与えられた値をもとにOptional<String>オブジェクトを生成します。Optional<String>は、nullであるかもしれないStringを意味します。これを読み取るのが以下のコードです。

  1. import java.util.Optional;
  2. ...中略...
  3. var name = ml.getNameById("Z-9999-0X");
  4. System.out.println(name.orElse("存在しません。").trim());

Optional<String>オブジェクトから値を取得するには、orElseメソッドを利用します。引数は値がnullの場合に採用するデフォルト値を意味します。先ほどのifによる分岐に比べると、コードがシンプルになっていますし、なによりOptionalクラスのままでは値を利用できないので、nullチェックが強制されます。null値の可能性がある戻り値では、このようにOptionalクラスでラップすることでnull安全なコードを記述できます。

ユーティリティ_目次
getPropertiesメソッド
Randomクラス
DateFormatクラス
NumberFormatクラス
Timerクラス
Optionalクラス

監修

山田祥寛(有限会社 WINGSプロジェクト)
静岡県榛原町生まれ。一橋大学経済学部卒業後、NEC にてシステム企画業務に携わるが、2003年 4 月に念願かなってフリーライターに転身。Microsoft MVP for Visual Studio and Development Technologies。執筆コミュニティ「WINGSプロジェクト(https://wings.msn.to/)」の代表でもある。主な著書に『改訂 3 版JavaScript 本格入門』(技術評論社)、「独習シリーズ(C#・Python・PHP・Ruby・JSP&サーブレットなど)」(翔泳社)、「速習シリーズ(ASP.NET Core・Vue.js・React・TypeScript・ECMAScript、Laravel など)」(Amazon Kindle)など。売り上げの累計は100万部を超える。