概要
今回は、java.util.Optionalの便利さと使用方法についての内容です。
環境
- Windows 10
- Oracle JDK 17
Optionalの利用が推奨される理由
値の取得時にnullが許容されない場合、Optionalを使用してnullを管理する方が、取得時に都度nullチェックを行うよりも優れている、というのが本稿の主旨です。
以前までは、「Optionalなど使用せずとも、受け取り側でnullのケースを処理すれば良い」と考えていました。
しかし、このOptional<T>
は便利な機能を有しています。
Optionalを使用する最大の利点は、コードをコンパイルする際、開発者にnullの可能性を事前に意識させる暗黙のガイドを提供することです。
具体的には、Optionalを使用することで、戻り値がnullの可能性がある場合に、その値を使用する前にチェックを強制してくれます。
これにより、値がnullである可能性を事前に気づき、NullPointerExceptionを防ぐことができます。
Optionalを使用しない場合
public String findUsernameById(Long userId) {
// ユーザー検索ロジック(省略)
return null; // ユーザーが見つからない場合
}
上記メソッドは、ユーザー名を取得することを試みますが、ユーザーが見つからない場合はnullを返します。
このメソッドを使用する際、戻り値がnullである可能性を常に考慮する必要があります。
使用する際にnullチェックを忘れると、NullPointerExceptionの発生の可能性があるからです。
Optionalを使用する場合
public Optional<String> findUsernameById(Long userId) {
// ユーザー検索ロジック(省略)
return Optional.empty(); // ユーザーが見つからない場合
}
上記のメソッドはOptionalを返します。このため、開発者は値を直接使用する前に、値の存在を確認する必要があります。
Optional<String> username = findUsernameById(userId);
username.ifPresent(name -> System.out.println("Username found: " + name));
上記のコードでは、ifPresentメソッドを使用して、usernameが値を含む場合のみユーザー名を出力します。
これにより、値がnullである場合のチェックを明示的に行い、NullPointerExceptionを防ぐことができます。
このように、Optionalを使用することで、値がnullである可能性に注意深くなり、そのような場合に適切に対応することがコンパイル時に促されます。
これにより、ランタイムエラーのリスクを低減することが出来ます。
Optionalの使用例
Optional.ifPresentOrElse()
Optional.ifPresentOrElse()は、値が存在する場合は引数で指定した1つ目の関数を実行し、存在しない場合は引数で指定した2つ目の関数を実行する。
Optional<String> username = findUsernameById(userId);
username.ifPresentOrElse(
name -> System.out.println("Username found: " + name), // 値が存在する場合に実行
() -> System.out.println("No username found") // 値が存在しない場合に実行
);
orElseThrow()
try {
// 値が存在しない場合に、NoSuchElementExceptionを投げる
String username = findUsernameById(userId)
.orElseThrow(() -> new NoSuchElementException("No username found for user ID: " + userId));
System.out.println("Username found: " + username); // 値が存在する場合に実行
// orElseThrowによって投げられるNoSuchElementExceptionをキャッチ
} catch (NoSuchElementException e) {
System.err.println(e.getMessage());
}
最後に
Optionalの使用により、値の取得時に都度行うnullチェックの場合と比べて、コードの堅牢性を向上させるとともに、NullPointerExceptionのリスクを効果的に低減できます。
より安全なコードを実現するために、Optionalの活用を積極的に行いましょう。