JSON を Java record に変換する(Java 16+)
JSON から不変な Java record を生成します。record は簡潔で equals / hashCode / toString を自動生成するため、Java 16 以降の DTO に最適です。
Foundations
詳細な説明
record:不変なデータキャリア
Java 16 はデータキャリア用の言語要素として record を導入しました。record は構成要素を 1 行で宣言し、コンパイラがアクセサ、equals()、hashCode()、toString() を自動合成します。
JSON の例
{
"id": 1,
"username": "alice",
"email": "alice@example.com"
}
生成される Java record
package com.example.model;
public record User(Integer id, String username, String email) {}
アクセサ
record はフィールド名そのものをアクセサ名にします(get プレフィックスなし)。
User user = new User(1, "alice", "alice@example.com");
System.out.println(user.username()); // "alice"
record が class より優れる場面
- DTO:層をまたぐデータ受け渡し
- API レスポンス:デシリアライズ後に変更しない不変なデータ
- パターンマッチ(Java 21+):switch 式での分解が綺麗
- Map / Set のキー:標準実装の
equalsとhashCodeで複合キーが安全
record が向かない場面
- 可変フィールドが必要 → record は設計上不変
- 継承が必要 → record は暗黙的に
java.lang.Recordを継承するため他クラスを継承できない - setter で独自バリデーションが必要 → コンパクト/標準コンストラクタでのみ検証
- Java 8 / 11 / 14 / 15 をターゲット → record は Java 16 が必須
カスタムコンストラクタ
コンパクトコンストラクタなら引数リストを再記述せずに入力検証できます。
public record User(Integer id, String username, String email) {
public User {
Objects.requireNonNull(id, "id");
if (username.isBlank()) throw new IllegalArgumentException("username");
}
}
record とフレームワーク
Spring Boot 3+、Jackson 2.12+、Hibernate 6+ はいずれも追加設定なしで record にデシリアライズできます。古いバージョンでは jackson-module-parameter-names などの追加モジュールが必要になる場合があります。
ユースケース
Java 17 LTS 以降を狙うモダンな Spring Boot 3 サービスは、Lombok 付き DTO を record で置き換えることで Lombok 依存そのものを取り除き、ビルド構成をシンプルにできます。