ヌル安全のために Optional を使用する
前のステップでは、オブジェクトを使用する前に明示的に null
かどうかをチェックすることで NullPointerException
を防ぐ方法を学びました。この方法は有効ですが、時にはコードが null
チェックで煩雑になることがあります。Java 8 では、潜在的に null
値を持つオブジェクトをより関数型で表現力豊かな方法で扱うために Optional
クラスが導入されました。
Optional
は、null ではない値を含む場合と含まない場合があるコンテナオブジェクトです。値が存在する場合、isPresent()
は true
を返し、get()
はその値を返します。値が存在しない場合、オブジェクトは空と見なされ、isPresent()
は false
を返します。空の Optional
に対して get()
を呼び出すと、NoSuchElementException
がスローされます。
Optional<Character>
を使用して、Character
が null
になる可能性を扱うように、例をリファクタリングしてみましょう。
-
WebIDE エディタで HelloJava.java
ファイルを開きます。
-
ファイルの内容全体を次のコードに置き換えます。
import java.util.Optional;
public class HelloJava {
public static void main(String[] args) {
Character myChar = null; // Still potentially null
// Create an Optional from the potentially null Character
Optional<Character> optionalChar = Optional.ofNullable(myChar);
// Use Optional methods to check and process the value
if (optionalChar.isPresent() && Character.isLetter(optionalChar.get())) {
System.out.println("myChar is a letter.");
} else {
System.out.println("myChar is not a letter or is null.");
}
// Another way using Optional's functional methods (more advanced)
// optionalChar.filter(Character::isLetter)
// .ifPresentOrElse(
// c -> System.out.println("myChar is a letter (using Optional methods)."),
// () -> System.out.println("myChar is not a letter or is null (using Optional methods).")
// );
}
}
このコードでは、以下のことを行っています。
Optional
クラスをインポートしています。
- 依然として
myChar
を潜在的に null
として宣言しています。
Optional<Character> optionalChar = Optional.ofNullable(myChar);
は Optional
オブジェクトを作成します。Optional.ofNullable()
は、値が null
になる可能性がある場合に使用されます。myChar
が null
の場合、optionalChar
は空の Optional
になります。myChar
に値がある場合、optionalChar
はその値を含みます。
- その後、
optionalChar.isPresent()
を使用して、Optional
が値を含んでいるかどうかをチェックし、optionalChar.get()
で値を取得して Character.isLetter()
に渡す前に確認します。これは前の null
チェックと似ていますが、Optional
API を使用しています。
- コメントアウトされた部分は、
filter
や ifPresentOrElse
などの関数型メソッドを使用して Optional
をより高度に使用する方法を示しています。これにより、特定のシナリオでコードをより簡潔にすることができます。この入門実験ではこの高度な使い方には焦点を当てませんが、知っておくと良いでしょう。
-
ファイルを保存します。
-
プログラムをコンパイルします。
javac HelloJava.java
-
プログラムを実行します。
java HelloJava
出力は前のステップと同じになるはずです。
myChar is not a letter or is null.
これは、Optional.ofNullable()
と isPresent()
を使用することで null
のケースを正しく扱えることを確認しています。
次に、myChar
を null
ではない文字に変更して、プログラムがどのように動作するかを見てみましょう。
-
HelloJava.java
ファイルを修正して、myChar
を文字(例えば 'A')に設定します。
import java.util.Optional;
public class HelloJava {
public static void main(String[] args) {
Character myChar = 'A'; // Now myChar has a value
// Create an Optional from the potentially null Character
Optional<Character> optionalChar = Optional.ofNullable(myChar);
// Use Optional methods to check and process the value
if (optionalChar.isPresent() && Character.isLetter(optionalChar.get())) {
System.out.println("myChar is a letter.");
} else {
System.out.println("myChar is not a letter or is null.");
}
}
}
-
ファイルを保存します。
-
プログラムをコンパイルします。
javac HelloJava.java
-
プログラムを実行します。
java HelloJava
今回は、出力は次のようになるはずです。
myChar is a letter.
これは、myChar
に値がある場合、optionalChar.isPresent()
が true
を返し、Character.isLetter()
のチェックが正しく実行されることを示しています。
Optional
を使用することで、コードがより読みやすくなり、値が存在しない可能性があることを明示的に示すことができ、予期しない NullPointerException
の可能性を減らすことができます。