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 のキー:標準実装の equalshashCode で複合キーが安全

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 依存そのものを取り除き、ビルド構成をシンプルにできます。

試してみる — JSON to Java

フルツールを開く