Java
Z
信頼度ランク
| S | 公式ソース確認済み |
| A | 成功実績多数・失敗例少数 |
| B | 賛否両論 |
| C | 動作未確認・セキュリティリスク高 |
| Z | 個人所感 |
NullPointerExceptionを確実に解決・予防する方法
JavaのNullPointerExceptionの原因パターンを分類し、Java 14以降のHelpful NullPointerExceptionsやOptionalを使った予防法まで解説します。
一言結論
NPEの根本対策はOptionalやObjects.requireNonNullで設計段階でnullを排除することで、Java 14以降のHelpful NPEは「どのチェーンでnullか」をスタックトレースに明示するため原因特定が格段に速い。
NullPointerException とは
null を参照しようとしたときに発生する例外です。Java で最も頻繁に遭遇するエラーの一つです。
String name = null;
System.out.println(name.length()); // NullPointerException!
よくある発生パターン
パターン1: 初期化し忘れ
List<String> items; // null のまま
items.add("hello"); // NPE
修正:
List<String> items = new ArrayList<>();
パターン2: メソッドの戻り値が null
Map<String, String> map = new HashMap<>();
String value = map.get("key"); // キーがなければ null
System.out.println(value.toUpperCase()); // NPE
修正:
String value = map.getOrDefault("key", "");
// または
String value = map.get("key");
if (value != null) {
System.out.println(value.toUpperCase());
}
パターン3: 配列の要素が null
String[] names = new String[3];
System.out.println(names[0].length()); // NPE(要素はまだ null)
修正:
String[] names = {"Alice", "Bob", "Charlie"};
パターン4: メソッドチェーン
String city = user.getAddress().getCity(); // address が null なら NPE
修正:
String city = Optional.ofNullable(user)
.map(User::getAddress)
.map(Address::getCity)
.orElse("Unknown");
Java 14以降: Helpful NullPointerExceptions
Java 14 から NPE のメッセージが詳しくなりました。
Java 13以前:
Exception in thread "main" java.lang.NullPointerException
Java 14以降:
Cannot invoke "String.length()" because "name" is null
有効化(Java 14〜17):
java -XX:+ShowCodeDetailsInExceptionMessages MyApp
Java 17以降はデフォルトで有効です。
Optional を使った予防
Optional はnullになりうる値をラップするコンテナです。
// 返り値をOptionalにする
public Optional<User> findUserById(int id) {
User user = database.find(id);
return Optional.ofNullable(user);
}
// 呼び出し側
findUserById(42)
.map(User::getName)
.ifPresent(name -> System.out.println("User: " + name));
// デフォルト値を使う
String name = findUserById(42)
.map(User::getName)
.orElse("匿名");
Objects.requireNonNull で引数を検証
public void process(String data) {
Objects.requireNonNull(data, "data must not be null");
// data が null なら NPE がここで発生(スタックトレースが明確になる)
data.toUpperCase();
}
Eclipseの@Nullableアノテーション活用
Eclipse は @Nullable/@NonNull アノテーションでnullチェックを静的解析できます。
import org.eclipse.jdt.annotation.NonNull;
import org.eclipse.jdt.annotation.Nullable;
public @Nullable String findName(int id) {
// nullable な返り値
}
public void greet(@NonNull String name) {
// name は non-null であることが保証される
}
Preferences > Java > Compiler > Errors/Warnings > Null analysis で設定します。
チェックリスト
- メソッドの戻り値が null になりうるか確認したか
- コレクションの要素を取り出す際にnullチェックをしているか
- フィールドが初期化されているか
- 外部入力(ユーザー入力、APIレスポンスなど)をnullチェックしているか
- Optional を適切に使っているか
NPE は「予防」がベストです。コードレビュー時にnullになりうる箇所を意識するだけで大幅に減らせます。