はじめに
この実験では、Java で Integer ラッパーオブジェクトを安全に扱う方法、特に null かどうかをチェックする方法を学びます。プリミティブ型の int とは異なり、Integer は null 参照を持つことができるオブジェクトであり、null チェックを行わないと、一般的な NullPointerException エラーが発生する可能性があります。
実際の例を通じて、基本的な == null チェックを探索し、null チェックと値の比較を組み合わせ、最後に、Java コードでより堅牢で表現力のある null 処理を行うために Optional クラスを活用する方法を学びます。
Integer ラッパーの null チェックを行う
このステップでは、Java で Integer ラッパーオブジェクトを扱う方法、特に null かどうかをチェックする方法を探索します。int のようなプリミティブ型とは異なり、Integer はクラスです。つまり、Integer 変数はオブジェクトへの参照を保持することができ、何のオブジェクトも参照しない場合は null になります。Java では、非常に一般的でプログラムをクラッシュさせる可能性のある NullPointerException エラーを防ぐために、null 値を適切に扱うことが重要です。
Integer の null チェックを実演するために、簡単な Java プログラムを作成しましょう。
WebIDE エディタで
HelloJava.javaファイルを開きます。前の実験を完了している場合、このファイルは~/projectディレクトリに既に存在するはずです。HelloJava.javaの既存のコードを以下のコードに置き換えます。public class HelloJava { public static void main(String[] args) { Integer myInteger = null; // Declaring an Integer and setting it to null // Check if myInteger is null if (myInteger == null) { System.out.println("myInteger is null."); } else { System.out.println("myInteger is not null. Its value is: " + myInteger); } // Let's try with a non-null Integer Integer anotherInteger = 10; // Declaring and initializing with a value // Check if anotherInteger is null if (anotherInteger == null) { System.out.println("anotherInteger is null."); } else { System.out.println("anotherInteger is not null. Its value is: " + anotherInteger); } } }このコードでは、以下のことを行っています。
Integer変数myIntegerを宣言し、明示的にnullに設定しています。if文を使用して、==演算子でmyIntegerがnullかどうかをチェックしています。これは Java でオブジェクト参照がnullかどうかをチェックする標準的な方法です。- 別の
Integer変数anotherIntegerを宣言し、値10を割り当てています。Java は自動的にプリミティブ型のint値10をIntegerオブジェクトに変換します(これをオートボクシングと呼びます)。 anotherIntegerに対して同じnullチェックを行っています。
HelloJava.javaファイルを保存します(Ctrl+S または Cmd+S)。ターミナルで
javacコマンドを使用してプログラムをコンパイルします。~/projectディレクトリにいることを確認してください。javac HelloJava.javaエラーがなければ、コンパイルは無事に完了し、
~/projectディレクトリにHelloJava.classファイルが作成されます。javaコマンドを使用してコンパイルされたプログラムを実行します。java HelloJava次のような出力が表示されるはずです。
myInteger is null. anotherInteger is not null. Its value is: 10この出力は、
nullのIntegerとnullでないIntegerの両方に対してnullチェックが正しく機能したことを確認しています。nullをチェックする方法を理解することは、Java プログラミングにおける基本的なスキルであり、特にラッパークラスや必ずしも値が割り当てられていないオブジェクトを扱う際に重要です。
null チェックと値チェックを組み合わせる
前のステップでは、Integer オブジェクトが null かどうかをチェックする方法を学びました。多くの場合、Integer が null でないことと、その値が特定の条件を満たすことを同時にチェックする必要があります。これらのチェックを組み合わせることは重要です。なぜなら、null の Integer の値にアクセスしようとすると、NullPointerException が発生するからです。
null チェックと値チェックを組み合わせる方法を実演するために、プログラムを修正しましょう。
WebIDE エディタで
HelloJava.javaファイルを開きます。既存のコードを以下のコードに置き換えます。
public class HelloJava { public static void main(String[] args) { Integer score = null; // Example 1: score is null // Check if score is not null AND its value is greater than 50 if (score != null && score > 50) { System.out.println("Score is not null and is greater than 50."); } else { System.out.println("Score is null or not greater than 50."); } Integer anotherScore = 75; // Example 2: score is 75 // Check if anotherScore is not null AND its value is greater than 50 if (anotherScore != null && anotherScore > 50) { System.out.println("anotherScore is not null and is greater than 50."); } else { System.out.println("anotherScore is null or not greater than 50."); } Integer yetAnotherScore = 40; // Example 3: score is 40 // Check if yetAnotherScore is not null AND its value is greater than 50 if (yetAnotherScore != null && yetAnotherScore > 50) { System.out.println("yetAnotherScore is not null and is greater than 50."); } else { System.out.println("yetAnotherScore is null or not greater than 50."); } } }この更新されたコードでは、以下のことを行っています。
- 論理 AND 演算子 (
&&) を使用して、score != nullとscore > 50の 2 つの条件を組み合わせています。 score != nullのチェックが最初に行われます。Java では、&&演算子は短絡評価を行います。つまり、最初の条件 (score != null) が偽の場合、2 番目の条件 (score > 50) は評価されません。これにより、scoreがnullの場合にNullPointerExceptionが発生するのを防ぎます。なぜなら、score > 50のコードは実行されないからです。- このロジックを 3 つの異なる
Integer変数でテストしています。1 つはnull、1 つはnullでなく 50 より大きい値、もう 1 つはnullでないが 50 より大きくない値です。
- 論理 AND 演算子 (
HelloJava.javaファイルを保存します。ターミナルで修正したプログラムをコンパイルします。
javac HelloJava.javaコンパイルされたプログラムを実行します。
java HelloJava次のような出力が表示されるはずです。
Score is null or not greater than 50. anotherScore is not null and is greater than 50. yetAnotherScore is null or not greater than 50.この出力は、組み合わせたチェックがどのように機能するかを示しています。最初のケースでは、
scoreがnullであることが正しく識別されています。2 番目のケースでは、anotherScoreがnullでなく 50 より大きいことが識別されています。3 番目のケースでは、yetAnotherScoreがnullではないが 50 より大きくないことが識別されています。オブジェクトのプロパティや値にアクセスする前にnullをチェックするこのパターンは、Java における基本的な安全対策です。
Optional を使用した安全なハンドリング
== null を使って null をチェックし、&& でチェックを組み合わせる方法は有効ですが、Java 8 では値が存在しない(つまり null)場合をより適切に扱うために Optional クラスが導入されました。Optional は、null ではない値を含む場合も含まない場合もあるコンテナオブジェクトです。Optional を使用すると、コードがより読みやすくなり、NullPointerException エラーが発生しにくくなります。
このステップでは、プログラムをリファクタリングして、潜在的に存在しない整数値を Optional<Integer> を使って扱うようにします。
WebIDE エディタで
HelloJava.javaファイルを開きます。既存のコードを以下のコードに置き換えます。
import java.util.Optional; public class HelloJava { public static void main(String[] args) { // Example 1: Optional containing a null value (empty Optional) Optional<Integer> optionalScoreNull = Optional.empty(); // Check if the Optional contains a value and if it's greater than 50 if (optionalScoreNull.isPresent() && optionalScoreNull.get() > 50) { System.out.println("optionalScoreNull is present and greater than 50."); } else { System.out.println("optionalScoreNull is empty or not greater than 50."); } // Example 2: Optional containing a non-null value (75) Optional<Integer> optionalScorePresent = Optional.of(75); // Check if the Optional contains a value and if it's greater than 50 if (optionalScorePresent.isPresent() && optionalScorePresent.get() > 50) { System.out.println("optionalScorePresent is present and greater than 50."); } else { System.out.println("optionalScorePresent is empty or not greater than 50."); } // Example 3: Optional containing a non-null value (40) Optional<Integer> optionalScoreNotGreater = Optional.of(40); // Check if the Optional contains a value and if it's greater than 50 if (optionalScoreNotGreater.isPresent() && optionalScoreNotGreater.get() > 50) { System.out.println("optionalScoreNotGreater is present and greater than 50."); } else { System.out.println("optionalScoreNotGreater is empty or not greater than 50."); } // A more functional way using Optional methods System.out.println("\nUsing Optional methods:"); optionalScoreNull.ifPresent(value -> System.out.println("Value from optionalScoreNull: " + value)); optionalScorePresent.ifPresent(value -> System.out.println("Value from optionalScorePresent: " + value)); optionalScoreNotGreater.ifPresent(value -> System.out.println("Value from optionalScoreNotGreater: " + value)); // Using orElse to provide a default value if Optional is empty Integer scoreOrDefault = optionalScoreNull.orElse(0); System.out.println("Value from optionalScoreNull with default: " + scoreOrDefault); // Using filter for conditional checks optionalScorePresent.filter(value -> value > 50) .ifPresent(value -> System.out.println("Filtered optionalScorePresent value: " + value)); optionalScoreNotGreater.filter(value -> value > 50) .ifPresent(value -> System.out.println("Filtered optionalScoreNotGreater value: " + value)); } }主な変更点を見てみましょう。
import java.util.Optional;:Optionalクラスをインポートします。Optional<Integer> optionalScoreNull = Optional.empty();:値が存在しないことを表す空のOptionalを作成します。Optional<Integer> optionalScorePresent = Optional.of(75);:Optional.of()を使って null ではない値を含むOptionalを作成します。なお、Optional.of()にnull値を渡すとNullPointerExceptionがスローされます。値がnullになる可能性がある場合は、Optional.ofNullable()を使用してください。optionalScoreNull.isPresent():このメソッドは、Optionalが値を含んでいるかどうかをチェックします。nullをチェックする代わりに、存在をチェックする推奨される方法です。optionalScoreNull.get():このメソッドは、Optionalから値を取得します。注意!Optionalが空の場合、get()を呼び出すとNoSuchElementExceptionがスローされます。そのため、get()を呼び出す前に常にisPresent()をチェックするか、空の場合を適切に処理する他のOptionalメソッドを使用する必要があります。optionalScoreNull.ifPresent(value -> ...):このメソッドは、Optionalが値を含んでいる場合にのみ、指定されたコードを実行します。値が存在する場合にその値に対してアクションを実行するクリーンな方法です。optionalScoreNull.orElse(0):このメソッドは、値が存在する場合はその値を返し、そうでない場合は指定されたデフォルト値(この場合は 0)を返します。optionalScorePresent.filter(value -> value > 50):このメソッドは、値が存在し、かつ指定された条件(値 > 50)に一致する場合に、その値を含むOptionalを返します。そうでない場合は、空のOptionalを返します。
HelloJava.javaファイルを保存します。ターミナルでプログラムをコンパイルします。
javac HelloJava.javaコンパイルされたプログラムを実行します。
java HelloJava次のような出力が表示されるはずです。
optionalScoreNull is empty or not greater than 50. optionalScorePresent is present and greater than 50. optionalScoreNotGreater is empty or not greater than 50. Using Optional methods: Value from optionalScorePresent: 75 Value from optionalScoreNotGreater: 40 Value from optionalScoreNull with default: 0 Filtered optionalScorePresent value: 75この出力は、
Optionalを使って値の存在または非存在を扱い、安全に操作を実行できることを示しています。if (isPresent() && get() > 50)のパターンはnullチェックに似ていますが、Optionalは他にも多くの便利なメソッド(ifPresent、orElse、filter、mapなど)を提供しており、潜在的に存在しない値を扱う際に、より表現力があり安全なコードを書くことができます。Optionalを使用することは、現代の Java 開発における良い習慣です。
まとめ
この実験では、Java で Integer ラッパーオブジェクトが null かどうかをチェックする方法を学びました。まず、Integer はクラスであり、プリミティブ型の int とは異なり、null 参照を保持できることを理解しました。単純な Java プログラムを使って基本的な == null チェックを実演し、NullPointerException を防ぐために null と非 null の Integer 変数の両方をどのように扱うかを示しました。



