Loading
  • LIGHT

  • DARK

ROUTE

ルートゼロの
アクティビティ

Spring Boot NullPointerException完全対策|3大原因と実装例まとめ

7

Spring Bootで頻発するNullPointerException、なぜ?どう防ぐ?


1. NullPointerExceptionの基礎を現場目線で整理

「こんなエラー、見覚えありませんか?」
Java開発でNullPointerException(以下NPE)に悩まされた経験、私たち開発者なら一度はあるはずです。
焦ってif文で“応急処置”したものの、レビューで「設計的に間違っている」と指摘されてしまう――そんなモヤモヤを一緒に解消しましょう。

用語解説:NullPointerException
Javaで参照型変数がnullのままアクセスされたときに発生する例外。主に「オブジェクトが存在しない状態」でメソッドやプロパティを呼び出すと起きます。

NullPointerExceptionとは?なぜ起きる?

NPEは、Javaで参照型変数がnullのままアクセスされた時に発生します。
例えば下記のようなコードです。

String name = null;
System.out.println(name.length()); // NPE発生

JDK14以降は「どの変数がnullだったか」までエラーメッセージで分かるようになりました。

Exception: Cannot invoke "String.length()" because "name" is null

原因追跡は容易になりましたが、根本的な設計改善が必要なのは変わりません。


2. 実務で頻発する3つの原因と対策

まず原因を3つに整理します――

①DBアクセス(JPA)でのnull

JPAのfindByIdはOptionalを返しますが、古いコードではnull返却が残りがちです。
(JPAの使い分けについては『JPA vs JDBC│Spring Bootでの実務的な使い分けと導入判断ガイド』をご参照ください)

用語解説:JPA(Java Persistence API)
Javaでデータベース操作を行うための標準API。エンティティ管理や永続化処理を簡単に記述できます。

用語解説:Optional
値が「存在する/しない」を明示的に扱えるJavaのラッパークラス。null安全な設計に役立ちます。

User user = repository.findByName("taro"); // 実装によってはnull
user.getEmail(); // NPEの可能性

対策:Optionalで明示的に存在確認を行いましょう。

Optional<User> userOpt = repository.findById(1L);
userOpt.ifPresent(user -> System.out.println(user.getEmail()));

②Spring BootのDI・バリデーションの落とし穴

用語解説:DI(Dependency Injection)
オブジェクトの依存関係を外部から注入する設計手法。Spring Bootでは@Autowiredで自動的にBeanを注入できます。

用語解説:Bean
Springで管理されるインスタンス。DIの対象となる部品です。

用語解説:@Valid/BindingResult
@Validは入力値のバリデーションを行うアノテーション。BindingResultはバリデーション結果を受け取るための引数です。

対策

  • @RequiredArgsConstructorやコンストラクタインジェクションを利用

  • Controllerで必ずBindingResultを引数に受ける

③フロント(Thymeleaf)とのデータ受け渡し

テンプレート内でnull参照が発生することも。
(Thymeleafの使い方やエラー対策については『Thymeleaf入門│Spring Bootで10分実践サンプル5選』をご参照ください)

用語解説:Thymeleaf
JavaのWebアプリケーションで使われるテンプレートエンジン。HTMLファイルに動的データを埋め込む際に利用します。

用語解説:DTO(Data Transfer Object)
データの受け渡し専用オブジェクト。null値を避けるため、初期値を設定して返す設計が推奨されます。

<p th:text="${user.name}"></p>
<!-- userがnullならNPE -->

対策

  • th:if="${user != null}"でガード

  • DTOでデフォルト値を設定して返す


3. 対策の実装パターン比較

if文・ガード節による基本対策

最もシンプルなのはif文でのnullチェック。
ただし小さい範囲で限定使用すべきです。

Optionalの使い方と注意点

OptionalはJava8以降の推奨手法です。

用語解説:Java8
2014年にリリースされたJavaのバージョン。Optionalやラムダ式など、null安全や関数型プログラミングの機能が追加されました。

Optional<String> name = Optional.ofNullable(user.getName());
System.out.println(name.orElse("未設定"));

注意:Optionalをフィールドに持たせるのはアンチパターン。戻り値に限定しましょう。

@NotNull/@Nullableアノテーションの活用

引数・戻り値に明示的に付与すると、IDEや静的解析で警告可能。
レビュー時に意図を共有できる利点があります。

用語解説:@NotNull/@Nullable
変数や引数が「null不可/null許容」であることを明示するアノテーション。IDEや静的解析ツールで警告を出せます。

空のコレクション/デフォルト値を返す設計

「nullを返す」より「空オブジェクトを返す」方が安全です。
(Spring BootでのList型・Map型の違いとBeanクラスの基礎は『【Spring Boot実践ガイド】List型・Map型の違いとBeanクラスの基礎&応用』をご参照ください)

用語解説:Collections.emptyList()
Javaで空のリストを返す標準メソッド。nullを返すより安全で、NPEを防げます。

return list == null ? Collections.emptyList() : list;

4. 設計思想と制度的理解でエラーを未然に防ぐ

「nullを返さない」API設計

  • API契約として「nullを返さない」をチームで徹底

  • 戻り値はOptionalか空オブジェクトに統一

コードレビューでのチェックリスト

  • 引数・戻り値のnull可能性を明示しているか

  • nullチェックが多すぎないか(設計の匂い)

  • Optionalが乱用されていないか


FAQ

  • JavaでNullPointerExceptionはなぜ起きる?
    → 参照型変数がnullのままアクセスされたためです。

  • Optionalを使えばNullPointerExceptionは完全に防げる?
    → 原則防げますが、設計段階でOptionalを適切に適用する必要があります。

  • Spring Bootで@ValidやBindingResultを使ってもエラーが通るのはなぜ?
    → ControllerメソッドでBindingResultを引数に受け取っていない可能性があります。

  • nullチェックを多用するとパフォーマンスに影響する?
    → 影響は軽微ですが、可読性や保守性が低下する方がリスクです。


結論と小さな行動提案

Spring Bootで頻発するNullPointerExceptionは、単なる「エラー解決テクニック」ではなく、設計思想とレビュー体制の問題と直結しています。
JPAの戻り値、DIの注入ミス、Thymeleafのnull参照など、現場で再現性の高い事例を理解することが第一歩です。

その上で、Optionalやアノテーション、静的解析ツールを活用し、「nullを返さない設計」を徹底することで、再発防止とコード品質の向上を両立できます。

ぜひコードをコピペして、まずは動かしてみてください。


もっとルートゼロを知りたいなら

DISCOVER MORE