Code Fix

上級

オートボクシングで起きる NullPointerException

Integerはnullを持てますが、演算時にintへ開封されます。Map.getの戻り値の受け方を扱います。

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

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          Integer n = null;
               ^
 4          System.out.println(n + 1);
 5      }
 6  }
Exception in thread "main" java.lang.NullPointerExceptionexited with code 1

Integerはnullを持てますが、演算時にintへ自動開封されます。nullの開封はNullPointerExceptionです。

直し方: IntegerInteger にします。

この問題を解いてみる →

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

パターン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("missing");
               ^
 8          System.out.println(v);
 9      }
10  }
Exception in thread "main" java.lang.NullPointerExceptionexited with code 1

getはキーがなければnullを返します。intで受けると開封が走って落ちるため、Integerで受けるか既定値を使います。

直し方: intInteger にします。

この問題を解いてみる →

パターン3

 1  import java.util.List;
 2  
 3  public class Main {
 4      public static void main(String[] args) {
 5          List<Integer> list = List.of(10, 20, 30);
 6          list.remove(Integer.valueOf(1));
                                 ^
 7          System.out.println(list);
 8      }
 9  }
remove(1) は添字1の要素を消し、remove(Integer.valueOf(1)) は値1を探して消す(どちらもコンパイルは通ります)

Listのremoveはintとオブジェクトで意味が変わる数少ない例です。意図をキャストで明示します。

直し方: Integer.valueOf(1)Integer.valueOf(1) にします。

この問題を解いてみる →

よくある誤解

NullPointerExceptionなのにnullを書いた記憶がない場合、自動開封を疑ってください。ラッパー型がintに変換される瞬間に起きます。

まとめ

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

演習をはじめる

関連するエラー

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