前回はenumを使って決まった種類の値を安全に管理する方法を学びました。
今回は「Optional」について解説します。 Javaプログラムでよく起きるエラーのひとつに「NullPointerException」があります。Optionalを使うことで、nullになる可能性のある値を安全に扱えるようになります。
NullPointerExceptionとは
NullPointerException(NPE)は、null の変数に対してメソッドを呼び出したり、フィールドにアクセスしたりしたときに発生するエラーです。Javaプログラムで最もよく見かけるエラーのひとつで、「nullポインタ例外」とも呼ばれます。
String name = null;
System.out.println(name.length()); // NullPointerException 発生!
これまでの対処法は、nullチェックを if 文で行うことでした。
if (name != null) {
System.out.println(name.length());
}
しかし、nullチェックが必要な箇所が増えると、コードが読みにくくなりがちです。Java 8から導入された Optional を使うと、「この値はnullかもしれない」という意図をコードで明示しながら、安全に操作できるようになります。
Optionalの基本
Optional<T> は、値が存在するかもしれないし、存在しないかもしれないことを表すクラスです。
// 値ありのOptionalを作る
Optional<String> opt1 = Optional.of("ぱんまる");
// 値なし(null)のOptionalを作る
Optional<String> opt2 = Optional.empty();
// nullかもしれない値からOptionalを作る
Optional<String> opt3 = Optional.ofNullable(someValue);
よく使うメソッドは以下の通りです。
isPresent() // 値が存在すればtrue
isEmpty() // 値が存在しなければtrue (Java 11以降)
get() // 値を取り出す(値がない場合は例外)
orElse() // 値がない場合のデフォルト値を指定
orElseGet() // 値がない場合の処理をラムダ式で指定
ifPresent() // 値がある場合だけ処理を実行
サンプルコード(Optionalの基本操作)
ファイル作成
「Java11」フォルダに OptionalTest.java という名前でファイルを作成します

コード入力
以下のコードを入力します。
import java.util.Optional;
public class OptionalTest {
public static void main(String[] args) {
Optional<String> optName = Optional.of("ぱんまる");
Optional<String> optEmpty = Optional.empty();
// isPresent で値の有無を確認
System.out.println("optName isPresent: " + optName.isPresent());
System.out.println("optEmpty isPresent: " + optEmpty.isPresent());
// get で値を取り出す
System.out.println("optName get: " + optName.get());
// orElse でデフォルト値を指定
System.out.println("optEmpty orElse: " + optEmpty.orElse("名無し"));
// orElseGet でラムダ式を指定
System.out.println("optEmpty orElseGet: " + optEmpty.orElseGet(() -> "デフォルト名"));
// ifPresent で値がある場合だけ処理
optName.ifPresent(name -> System.out.println("こんにちは、" + name + "さん!"));
optEmpty.ifPresent(name -> System.out.println("これは表示されません"));
}
}

コンパイル
javac OptionalTest.java

実行
java OptionalTest
実行結果は次のようになります。
optName isPresent: true
optEmpty isPresent: false
optName get: ぱんまる
optEmpty orElse: 名無し
optEmpty orElseGet: デフォルト名
こんにちは、ぱんまるさん!

サンプルコード(Optionalとメソッドの組み合わせ)
ファイル作成
「Java11」フォルダに UserFinder.java という名前でファイルを作成します

コード入力
以下のコードを入力します。
import java.util.Optional;
public class UserFinder {
public static Optional<String> findUserById(int id) {
if (id == 1) {
return Optional.of("ぱんまる");
} else {
return Optional.empty();
}
}
public static void main(String[] args) {
int[] ids = {1, 2, 3};
for (int id : ids) {
Optional<String> user = findUserById(id);
String result = user.orElse("ユーザーが見つかりません");
System.out.println("ID " + id + " : " + result);
}
}
}

コンパイル
javac UserFinder.java

実行
java UserFinder
実行結果は次のようになります。
ID 1 : ぱんまる
ID 2 : ユーザーが見つかりません
ID 3 : ユーザーが見つかりません

コードの解説
Optional.of("ぱんまる") は値ありのOptionalを作ります。Optional.empty() は値なし(nullに相当)のOptionalを作ります。値がnullかもしれない場合は Optional.ofNullable(value) を使うと、nullなら自動的に Optional.empty() になります。
orElse("名無し") は、値がない場合に括弧内の値を返します。値がある場合はそちらが使われます。orElseGet(() -> "デフォルト名") は、orElse と似ていますが、ラムダ式を使って値が必要になったときだけ処理を実行するため、デフォルト値の生成コストが高い場合に向いています。
ifPresent(name -> ...) は値がある場合だけラムダ式の処理を実行します。if (opt.isPresent()) { ... } と書く代わりにこちらを使うと、より簡潔に書けます。
findUserById メソッドの戻り値を Optional<String> にすることで、「この戻り値はnullになることがある」という意図がメソッドのシグネチャから明確に伝わります。呼び出す側では orElse などで必ずnullの場合の処理を書くことが促されるため、nullチェックの書き忘れを防ぎやすくなります。
なお、get() は値がない状態で呼ぶと NoSuchElementException が発生します。get() を使う前には必ず isPresent() で確認するか、orElse や ifPresent を使う書き方が推奨されます。
まとめ
Optionalを使うことで、nullになる可能性のある値を明示的に表現し、NullPointerExceptionを防ぎやすくなります。orElse でデフォルト値を指定したり、ifPresent で値がある場合だけ処理したりと、nullチェックのif文を使わずに安全なコードが書けるようになります。メソッドの戻り値にOptionalを使うことで、「この値はnullかもしれない」という意図をコードで伝えることができ、呼び出す側での対処が促されます。nullとの戦いはJavaプログラミングの永遠のテーマですが、Optionalをうまく活用することでより安全で読みやすいコードに近づけます。
2026/07/01(水) ぱんまる


コメント