2
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

Javaの型安全とOptional<T>を上手く使えば便利になるという話

Posted at

概要

今回は、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の活用を積極的に行いましょう。

参考リンク

Java JDK 17 ドキュメント

2
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?