Javaでnull判定をチェックする方法をわかりやすく解説!

- SE
- Javaのnullとはどのような状態のことをいうのでしょうか。
- PM
- インスタンスを参照する変数が、インスタンスを参照していない状態です。ただこれだけでは分かりにくいので、一緒に学んでいきましょう。
この記事でわかること
Javaのnull判定とは?
Javaのnullとは、インスタンスを参照する変数が、インスタンスを参照していない状態です。ただこれだけでは分かりにくいと思うので、実例を挙げます。
Object obj = new Object();
この場合、objはObject型の参照変数で、インスタンスを参照している状態です。
obj = null;
こうするとobjはインスタンスを参照していない状態になります。これがnullです。nullは参照変数が空の状態を表していて、この機能が必要な場面は色々とあります。例えば何かの処理が終了した時に、その処理に使用した変数にnullを入れることで終わったことを示す時です。
JavaはNullPointerExceptionのリスクが常にある
しかし例えば以下のようにnullの参照変数のメソッドにアクセスしたりすると、
obj = null;
System.out.println(obj.getClass());
NullPointerExceptionが発生して、例外処理していない場合は、プログラムが異常終了してしまいます。そのためJavaでは、以下のようにnullかどうかの判定を常に入れることがとても重要なのです。
if (obj != null) {
System.out.println(obj.getClass());
}
なおC#などの他の言語ではnull自体を廃止しようという動きもありますが、Javaでは導入されていません。
Objectsによるnull判定
Javaのnull判定の基本は上に書いたようなif文です。それ以外では、以下のようにtry~catchでNullPointerExceptionの発生に備えることも一つの方法です。これで判定漏れがあっても対処できます。
try {
System.out.println(obj.getClass());
} catch (Exception e) {
// 例外の場合の処理
}
Java 7から導入されたObjectsクラスでも、以下のようにnull判定と非null判定ができます。なお利用する場合はソースの先頭に「import java.util.*;」の追加が必要です。
Object obj = null;
if (Objects.isNull(obj)) {
System.out.println(“”objはnullです。””);
}
obj = new Object();
if (Objects.nonNull(obj)) {
System.out.println(“”objはnullではありません。””);
}
Objects.equalsの使い方
Javaにおいて2つの参照変数があるとして、それが同じインスタンスかどうか判定するには以下のようにします。
if (obj1.equals(obj2)) {
// 同じ内容だった場合の処理
}
しかし、obj1がnullの場合はNullPointerExceptionが発生してしまいます。ただしobj1もobj2もnullだった場合は、等しいという結果にしたい時もあります。そういった時に、以下のようにObjects.equalsを使えばスマートに判定できます。
if (Objects.equals(obj1, obj2)) {
// 同じ内容だった場合の処理
}
これならNullPointerExceptionが発生せず、obj1とobj2が両方nullだった場合も等しいと判定されます。
Objects.requireNonNullの使い方
Objects.requireNonNullはパラメータを判定し、nullであればNullPointerExceptionを発生します。そうでなければそのまま返します。
Object obj2 = Objects.requireNonNull(obj1);
文字列を追加すると、NullPointerExceptionにそのメッセージを追加できます。
Object obj2 = Objects.requireNonNull(obj1, “”nullでした。””);
Objects.toStringの使い方
Objects.toStringはパラメータを判定し、nullでなければtoStringを呼び出した結果を返し、nullならば””null””という文字列を返します。
String str1 = null;
String str2 = Objects.toString(str1);
System.out.println(str2);
実行結果は以下になります。
null
以下のように文字列を追加すると、nullだった場合に置き換える文字列を設定できます。
String str2 = Objects.toString(str1, “”nullでした。””);
requireNonNullと違いNullPointerExceptionを防げるので、こちらの方が使う機会が多いかもしれません。
Optionalクラスでnull判定自体をなくす
Java 8から、nullチェックを不要にするためのクラスのOptionalが追加されました。String型で利用するには以下のようにします。なおソースの先頭には「import java.util.*;」を追加してください。
String str = null;
Optional<String> strOpt = Optional.of(str);
これを実行すると、NullPointerExceptionが発生します。Optional.ofはnullを許容しないからです。Optionalの中身を空にするには、以下のようにemptyを代入します。
Optional<String> strOpt = Optional.empty();
Optionalの値の取得
ofではなくofNullableで代入すると、パラメータがnullだった場合はemptyを代入します。そのためNullPointerExceptionは発生しません。
Optional<String> strOpt = Optional.ofNullable(str);
Optionalの中身を取得するにはgetを使います。
System.out.println(strOpt.get());
ただしOptionalの中身がemptyだった場合はNoSuchElementExceptionが発生します。Optionalは例外が発生しなくなるわけではないのです。
orElseで例外発生を防ぐことができる
Optionalに中身があるかどうかの判定は以下のようにisPresentを使用します。
if (strOpt.isPresent()) {
System.out.println(strOpt.get());
}
これではnull判定するのと変わらないと思う人がいるかもしれません。しかし値の取得に、getの代わりにorElseを利用すれば、例外の発生を防ぐことができて、isPresentによる判定も不要になります。
System.out.println(strOpt.orElse(“”nullです。””));
この場合、strOptがempyなら例外が発生せずに””nullです。””が表示されます。
orElseGetとorElseThrow
orElseGetを使うと、中身がemptyだった場合にラムダ式の戻り値に置き替えられます。
int mode = 1;
System.out.println(strOpt.orElseGet(() -> {
if (mode==0)
return “”nullです。””;
else
return “”nullでした。””;
}));
orElseThrowを使うと、emptyだった場合に例外を発生させます。この場合は自分で作ったExceptionクラスを指定すると良いです。
System.out.println(strOpt.orElseThrow(Exception::new));
- SE
- avaのnull判定についてよく理解できました。
- PM
- 場合によってはnull判定自体をなくすという方法もありますので、状況によって使い分けましょう。
Javaのnull判定を忘れずに
Javaのnull判定について様々な方法を紹介しました。Java 8で新しく導入されたOptionalクラスも、結局は例外が発生するのであまり意味がないと思うのであれば、if文による初歩的な方法でもかまいません。
Javaプログラミングでnull判定の入れ忘れだけはしないようにしましょう。