Code Fix

中級

NullPointerException の原因と直し方

nullに対する操作で発生します。発生箇所の特定方法と、そもそもnullを持ち回さない設計を扱います。

エラーメッセージの読み方

Exception in thread "main" java.lang.NullPointerException:
main
スレッド名 — mainなら起動直後の処理で発生しています
java.lang
パッケージ — java.lang なら標準の基本例外です
NullPointerException
例外クラス — 何が起きたか。ここを検索するのが最短です

このエラーが出る典型パターン

パターン1

 1  public class Main {
 2      public static void main(String[] args) {
 3          String s = null;
                         ^
 4          System.out.println(s.length());
 5      }
 6  }
Exception in thread "main" java.lang.NullPointerException: Cannot invoke "String.length()" because "s" is nullexited with code 1

nullは実体がない状態です。空文字""は長さ0のStringという実体なので、メソッドを呼べます。

直し方: null"" にします。

この問題を解いてみる →

広告
広告スロット(未設定)

パターン2

 1  import java.util.HashMap;
 2  import java.util.Map;
 3  
 4  public class Main {
 5      public static void main(String[] args) {
 6          Map<String, Integer> m = new HashMap<>();
 7          int v = m.get("x")            ;
                                ^
 8          System.out.println(v);
 9      }
10  }
Exception in thread "main" java.lang.NullPointerExceptionexited with code 1

存在しないキーのgetはnullを返します。intへの代入時に自動開封が起きてNullPointerExceptionになります。

直し方: get("x")getOrDefault("x", 0) にします。

この問題を解いてみる →

パターン3

 1  public class Main {
 2      static String find(int n) {
 3          if (n > 0) return "found";
 4          return null;
                     ^
 5      }
 6      public static void main(String[] args) {
 7          System.out.println(find(-1).length());
 8      }
 9  }
Exception in thread "main" java.lang.NullPointerExceptionexited with code 1

nullを返すメソッドは呼び出し側にnullチェックを強制します。空の値を返すほうが安全です。

直し方: null"" にします。

この問題を解いてみる →

よくある誤解

nullを代入した行では落ちません。使った行で落ちます。スタックトレースの先頭が示すのは「使った場所」です。

まとめ

NullPointerExceptionは中級でつまずきやすい項目です。上の3パターンを実際に手で直すと、エラーメッセージのどこを読めばよいかが掴めます。

演習をはじめる

関連するエラー

広告
広告スロット(未設定)