NullPointerExceptionに悩まされたことはありませんか?このエラーは、Javaプログラミングでは一般的で厄介な問題の1つです。
本記事では、nullの基本概念から、判定方法、さらには効果的な対策まで、詳しく解説します。
「==」演算子、Objects.isNull()メソッド、Optional<T>クラスなど、さまざまなnull判定テクニックを学び、より安全なコーディングスキルを身につけましょう。
Contents
nullとは

nullは、Javaのキーワードの1つで、プログラミング上の重要な概念です。
nullはヌルまたはナルと読み、ラテン語のnullusに由来しています。
他のプログラミング言語にも、同様のnilやNoneがありますが、なかでもJava実務でのnullの重要度は高いです。
Javaにおけるnullの基本
Javaでは、nullはオブジェクト型変数が 何も参照していない状態 を表します。つまり、変数がメモリ上のどのオブジェクトも指していないことを意味します。
プリミティブ型(int、booleanなど)には直接nullを代入できませんが、オブジェクト型(String、Integer、Listなど)にはnullを代入できます。
String name = null; // 有効
int number = null; // コンパイルエラー
Javaプログラミングでは、nullを適切に扱えないと、予期せぬエラーやバグの原因になる可能性があります。
null判定の必要性について
null判定は、プログラムの安全性と堅牢性を高めるために不可欠です。主な理由として、NullPointerExceptionの回避とデータの整合性維持が挙げられます。
NullPointerExceptionは、nullのオブジェクトに対してメソッドを呼び出したり、プロパティにアクセスしようとしたときに発生する例外です。このエラーはプログラムの実行を中断させる可能性がありますが、事前にnull判定をおこなえば防ぐことができます。
String text = null;
if (text != null) { // メソッドを使用する前にnullを判定
System.out.println(text.length()); // lengthメソッドを安全に実行できる
} else {
System.out.println(“textはnullです”);
}
他方で、プログラムの整合性を確保するためには、nullがオブジェクト変数に設定されるロジックを理解していないと、意図せず不完全なデータを作成・保存してしまい、将来のエラーにつながる可能性があります。
null判定と空文字列との違いについて
nullと空文字列は異なる概念です。nullは参照がない状態を表すのに対し、空文字列は長さが0の文字列オブジェクトです。
メモリ上では、nullは何も割り当てられていませんが、空文字列は実際にオブジェクトとして存在します。
String nullString = null;
String emptyString = “”;
System.out.println(nullString == null); // true
System.out.println(emptyString == null); // false
System.out.println(emptyString.length()); // 0
適切な使い分けは、プログラムの意図によって異なります。
例えば、ユーザー入力がない場合はnullを、入力はあったが何も入力されなかった場合は空文字列を使うなど、状況に応じて使い分けます。
Javaでnull判定をおこなう方法
Javaでnull判定をおこなうには、主に3つの方法があります。
- ・「==」演算子を使用する方法
- ・Java 8以降で導入されたObjects.isNull()メソッドを使用する方法
- ・Optional<T>クラスを活用する方法
「==」演算子は直感的でわかりやすいですが、Objects.isNull()メソッドはNullPointerExceptionを防ぐのに役立ちます。Optional<T>クラスは、nullの可能性がある値を安全に扱うためのより高度な方法です。
以下に、null判定の例を示します。
String 文字列 = null; // nullの可能性がある文字列を宣言
if (文字列 == null) { // 「==」演算子を使用してnull判定
System.out.println(“1. ==演算子: 文字列はnullです”);
} else {
System.out.println(“1. ==演算子: 文字列はnullではありません”);
}
if (Objects.isNull(文字列)) { // Objects.isNull()メソッドを使用してnull判定
System.out.println(“2. Objects.isNull(): 文字列はnullです”);
} else {
System.out.println(“2. Objects.isNull(): 文字列はnullではありません”);
}
// Optional<T>クラスを使用したnull判定
Optional<String> オプション文字列 = Optional.ofNullable(文字列); // 文字列をOptionalでラップ
if (オプション文字列.isPresent()) { // 値が存在するかチェック
System.out.println(“3. Optional: 文字列は存在し、値は: ” + オプション文字列.get());
} else {
System.out.println(“3. Optional: 文字列は存在しません(null)”);
}
// 出力:
// 1. ==演算子: 文字列はnullです
// 2. Objects.isNull(): 文字列はnullです
// 3. Optional: 文字列は存在しません(null)
上記のように、適切なnull判定をすれば、NullPointerExceptionを防ぎ、より安全なプログラムを作成できます。
nullと空文字列を確認する方法
nullと空文字列を確認する方法としては、次の3つがあります。
- ・String.isEmpty()は文字列が空かどうかを判定しますが、nullチェックはしません。
- ・StringUtils.isBlank()は、null・空文字列・空白のみの文字列をすべて「空」とみなします。
- ・Objects.equals()は、null安全な比較をします。
以下に、nullと空文字列を判定する例を示します。
String 文字列 = “”;
if (文字列 != null && !文字列.isEmpty()) {
System.out.println(“文字列はnullでも空文字列でもありません”);
if (StringUtils.isBlank(文字列)) {
System.out.println(“文字列は空白のみの文字列です”);
}
} else {
System.out.println(“文字列はnullか空文字列です”);
}
if (Objects.equals(文字列, “”)) {
System.out.println(“文字列は空文字列です”);
} else {
System.out.println(“文字列は空文字列ではないかnullです”);
}
エラーが発生したときの対処方法は?
本項では、nullに関して発生しやすいエラーとしてNullPointerExceptionの基本的なデバッグ方法と、よくあるバグの対策を説明します。
NullPointerExceptionのデバッグでは、まずスタックトレースを確認し、エラーが発生した箇所を特定します。そして、変数の値をログ出力やデバッガで確認し、nullになっている原因を突き止めます。原因が分かったら、null判定や例外処理を追加して対策を講じます。
例外処理の実装では、try-catch文を使用してエラーを捕捉し、適切な処理をおこないます。
try {
String 結果 = オブジェクト.メソッド(); // nullを返す可能性があるメソッド
System.out.println(結果.length()); // 結果がnullだった場合、この行で例外が発生します
} catch (NullPointerException 例外) {
System.out.println(“オブジェクトがnullです”); // 例外時はメッセージを表示し、処理を継続
}
よくあるnull関連バグと対策
null関連のバグは頻繁に発生しますが、主な原因・対策を知ると、多くのバグを未然に防げます。
また、Optional<T>クラスを使用すると、nullの可能性を明示的に表現し、より安全で理解しやすいコードを書けるので、おすすめです。
参考リンク:Optional<T>::ifPresentOrElse
未初期化変数の使用
変数を宣言したあと、初期化せずに使用するとNullPointerExceptionが発生します。
対策として、変数を宣言する際に初期値を設定するか、使用前に必ずnull判定をおこないます。
String 名前 = null;
if (名前 != null) { // null判定
System.out.println(名前.length());
} else {
System.out.println(“名前が設定されていません”);
}
// Optional<T>クラスを使用する場合
Optional<String> 名前 = Optional.ofNullable(null);
名前.ifPresentOrElse(
n -> System.out.println(n.length()),
() -> System.out.println(“名前が設定されていません”)
);
API戻り値のnullチェック漏れ
外部APIやメソッドの戻り値がnullになる可能性を考慮せずに使用すると、エラーが発生します。
対策として、戻り値を使用する前に必ずnull判定をおこないます。
List<String> データ = API.データ取得();
if (データ != null && !データ.isEmpty()) { // null判定
for (String 項目 : データ) {
System.out.println(項目);
}
} else {
System.out.println(“データがありません”);
}
// Optional<T>クラスを使用する場合
Optional<List<String>> データ = Optional.ofNullable(API.データ取得());
データ.ifPresentOrElse(
リスト -> リスト.forEach(System.out::println),
() -> System.out.println(“データがありません”)
);
条件分岐でのnull考慮漏れ
条件分岐でnullの可能性を考慮しないと、予期せぬ動作やエラーが発生します。
対策として、nullの場合の処理も明示的に記述します。
if (オブジェクト != null && オブジェクト.条件()) {
// 条件を満たす場合の処理
} else if (オブジェクト == null) {
// オブジェクトがnullの場合の処理
} else {
// 条件を満たさない場合の処理
}
まとめ
Javaでのnull判定は、NullPointerExceptionの回避や整合性の維持に不可欠です。
「==」演算子、Objects.isNull()メソッド、Optional<T>クラスなど、状況に応じた適切な方法を選択しましょう。
今日から、より安全なJavaプログラミングを始めてみませんか?
フリーランスの案件をお探しの方はTechReachにご相談ください。
TechReachを運営する株式会社アールストーンはIT・Web業界特化で15年以上の実績がございます。
そのため、高単価・高品質な数多くの案件紹介が可能です。
また一人のコンサルタントが企業と求職者様の担当を行う「両面型エージェント」を採用しているため、あなたの希望に合う案件がきっと見つかるはずです。
TechReachを活用して、理想の案件を見つけましょう!