AIによる要約
Map.ofはnullのキーと値を許可しないため、Map作成時点でNullPointerExceptionになります。getを呼んだ時ではありません。また、作成したMapへputやremoveもできません。HashMapはnullを許可しますが、キー未登録と登録済みnullの区別が必要になります。固定データならMap.of、値の追加・変更やnullを扱うなら要件に合う別の表現を選びます。
この記事はXへ投稿したJavaクイズの詳しい解説です。まず問題を解きたい方は、Xの元ポストを開くことができます。


Java 9以降では、少数の固定データを簡潔に作るためにMap.ofを使えます。テストデータや区分値の対応表では便利ですが、HashMapと同じ感覚でnullを渡すと、その行で処理が停止します。
特に、画面入力や設定ファイルから取得した値をそのままMap.ofへ渡すコードは、正常データでは動いても任意項目が未入力のときだけ失敗します。APIの仕様と業務上のnullの意味を分けて考えましょう。
この記事のポイント
- Map.ofはnullのキーと値を許可しない
- 例外はMap作成時点で発生する
- Map.ofで作ったMapは変更できない
- HashMapのnull許可とは設計上の意味が異なる
- 未設定はnull以外の型や状態で表せないか検討する
まずはXのJavaクイズを確認する

Map<String, String> values =
Map.of("A", null);
System.out.println(values.get("A"));答えはNullPointerExceptionです。Map.ofはキーにも値にもnullを許可せず、printlnより前の作成処理で例外になります。

例外はgetではなくMap作成時に発生する
コードを上から追うと、最初にMap.of("A", null)が評価されます。この呼び出しがMapを返せないため、変数valuesへの代入も、後続のgetも実行されません。障害ログの行番号もMap.ofの行を指します。
String value = null;
Map<String, String> map = Map.of("A", value);
// ここでNullPointerException『getしたらnullになった』と誤認すると、containsKeyやObjects.requireNonNullを後段へ足しても直りません。スタックトレースの先頭と評価順を確認し、例外が起きた行を正しく特定します。
Map.ofがnullを許可しない理由
Map.ofで作るMapは、作成後に内容を変更しない小さな固定Mapです。nullを禁止することで、『キーがない』と『値がnull』の曖昧さを持ち込まず、要素の存在を明確にしています。
これはすべてのMapがnullを禁止するという意味ではありません。Mapはインターフェースであり、nullを許可するか、変更できるか、スレッドセーフかは実装や生成方法によって異なります。変数型がMapでも契約は同じではありません。
Map.ofの主な特徴
- nullキーを渡せない
- null値を渡せない
- put・remove・clearで変更できない
- 同じキーを2回指定できない
- 要素の走査順を業務仕様として当てにしない
HashMapならnullを入れられる
HashMapは1つのnullキーと複数のnull値を許可します。そのため次のコード自体は動きます。
Map<String, String> map = new HashMap<>();
map.put("A", null);
System.out.println(map.get("A")); // null
System.out.println(map.get("B")); // nullただし、Aは登録済みnull、Bは未登録なのに、getの戻り値はどちらもnullです。区別が必要ならcontainsKeyを使います。技術的にnullを入れられることと、業務設計として入れるべきことは別です。
設定値やDTOからMap.ofを作るときの注意
固定の文字列だけでMap.ofを作る場合はnullになりません。危険なのは、外部から取得した値を直接渡す場合です。任意入力、DBのNULL、環境変数未設定、JSONの項目不足などがnullの入口になります。
Map<String, String> attributes = Map.of(
"department", userForm.getDepartment(),
"extension", userForm.getExtension());内線番号が任意項目なら、未入力時に失敗します。null項目をMapから除外する、空文字へ変換する、専用DTOを使う、必須入力にするなど、仕様に合う対応を選びます。とりあえず空文字にする修正は、未設定と空文字の意味が同じ場合だけにします。
変更したいなら最初から別のMapを選ぶ
Map.ofで作った後にputするとUnsupportedOperationExceptionになります。初期値を簡潔に書きつつ後で変更したいなら、HashMapのコンストラクタへ渡して可変コピーを作ります。
Map<String, String> map = new HashMap<>(
Map.of("status", "NEW"));
map.put("owner", "U001");一方、固定の区分表や定数として使うなら、変更できない方が安全です。『念のためHashMap』にすると、後続処理が誤って書き換えても気付きにくくなります。ライフサイクルから可変・不変を選びます。
nullを持たせない設計を検討する
Mapの値にnullを入れると、未取得、該当なし、入力なし、取得失敗など複数の意味が混ざりやすくなります。必要ならOptional、状態を持つDTO、enum、結果クラスで意味を分けます。
record UserAttribute(String department, Optional<String> extension) {}
UserAttribute attribute = new UserAttribute(
department, Optional.ofNullable(extension));Optionalをフィールドに使うかはプロジェクト方針もあります。大切なのはOptionalそのものではなく、『このnullは何を意味するか』を型や契約で説明できることです。
JUnitで作成時の契約を確認する
ライブラリ仕様をそのままテストする必要はありませんが、外部入力から固定Mapを作る自作メソッドには、任意項目null時の期待動作を残します。
@Test
void 任意項目がnullならMapから除外する() {
Map<String, String> actual = mapper.toAttributes(
new UserForm("営業", null));
assertEquals("営業", actual.get("department"));
assertFalse(actual.containsKey("extension"));
}例外にする設計なら、どの例外型とエラーコードに変換するかをテストします。NullPointerExceptionが偶然そのまま500エラーになる状態は、利用者にも運用者にも意図が伝わりません。
現場レビューでよくある指摘
Map.ofのレビューでは、短く書けているかより、入力がnullにならない契約と作成後に変更しない意図が成立するかを見ます。
// レビューコメント例
extensionは任意入力なのでnullになります。Map.ofはnullを許可しません。
未設定項目を除外するか、専用DTOで表現してください。
// レビューコメント例
このMapは後続でputしています。Map.ofの戻り値は変更できないため、
最初からHashMapを使うか、可変コピーを作ってください。
// レビューコメント例
値nullとキー未登録を区別する仕様でしょうか。
HashMapへnullを入れる前に、状態の表現方法を整理してください。NullPointerExceptionへ場当たり的なnullチェックを足す前に、どの入力がnullになり、Mapにその状態を保持する必要があるか確認します。作成時と利用時の契約をそろえるのが先です。
提出前のセルフチェック
レビュー前に確認すること
- Map.ofへ渡す値がnullにならないか
- 例外発生行を作成時点として確認したか
- 作成後にputやremoveをしていないか
- キー未登録と値nullを区別する必要があるか
- 固定Mapとして不変にする意図があるか
- 同一キーや順序へ依存していないか
- 任意入力・DB NULL・環境変数未設定をテストしたか
Javaコレクションを体系的に学ぶ参考書
Mapは生成方法ごとにnull、変更可否、順序の契約が異なります。コレクションの基本をまとまって確認すると、短いファクトリメソッドを安全に選べます。
スッキリわかるJava入門 第5版
Java文法とオブジェクト指向を、最初から整理する一冊。
豊富な図とサンプルで、変数、条件分岐、クラス、例外処理まで順番に学べます。Javaの最初の教科書を探している人向けです。
- Javaを基礎から体系的に学びたい
- Java 25 LTS対応の入門書を選びたい
当サイトはAmazonアソシエイト・プログラムの参加者です。価格・在庫・配送条件はAmazonでご確認ください。
この記事とあわせて読みたい
まとめ
Map.ofはnullのキーと値を許可しないため、nullを渡すとMap作成時点でNullPointerExceptionになります。また、作成したMapはputやremoveで変更できません。
HashMapならnullを格納できますが、未登録との区別が必要です。入力がnullになる理由とMapのライフサイクルを確認し、不変Map、可変Map、専用DTOのどれが意図を表せるか選んでください。
