🦦

JAVAのRecordクラスについて

2025/03/04に公開

はじめに

Java 14でプレビュー機能として導入され、Java 16から正式にサポートされたRecordクラスは、データキャリアとしてのシンプルなクラスを簡潔に定義するための新しい構文を提供します。従来のPOJO(Plain Old Java Object)やDTO(Data Transfer Object)に代わるものとして、より簡潔かつ安全にデータを表現できます。

本記事では、Recordクラスの基本文法から、コードサンプル、応用的な使い方、利用ケース、実装時の注意点について最新の情報を交えながら解説します。


Recordクラスの基本文法

Recordクラスとは?

Recordクラスは、イミュータブルなデータクラスを簡単に定義するためのJavaの新しい構文です。Recordクラスを定義すると、自動的に以下のメソッドが生成されます。

  • コンストラクタ
  • getterメソッドname() 形式)
  • equals() メソッド
  • hashCode() メソッド
  • toString() メソッド

基本構文

public record Person(String name, int age) {}

このコードで、Person というRecordクラスが定義され、以下の機能が自動的に提供されます。

  • コンストラクタ: new Person(String name, int age)
  • getterメソッド: name()age()
  • equals()とhashCode(): オブジェクトの内容に基づく比較とハッシュコード生成
  • toString(): "Person[name=John, age=30]" のような形式でオブジェクトを文字列化

Recordクラスのコードサンプル

以下は、Recordクラスを使用した基本的なコードサンプルです。

public class RecordExample {
    public static void main(String[] args) {
        Person person = new Person("John Doe", 30);

        // getterメソッドを使用して値を取得
        System.out.println(person.name());  // 出力: John Doe
        System.out.println(person.age());   // 出力: 30

        // 自動生成されたtoString()メソッドの使用
        System.out.println(person);         // 出力: Person[name=John Doe, age=30]

        // equals()とhashCode()の使用
        Person anotherPerson = new Person("John Doe", 30);
        System.out.println(person.equals(anotherPerson));  // 出力: true
        System.out.println(person.hashCode() == anotherPerson.hashCode());  // 出力: true
    }
}

public record Person(String name, int age) {}

応用的な使い方

1. バリデーション付きコンストラクタの定義

Recordクラスでも、コンストラクタに追加のロジックを含めることができます。例えば、引数のバリデーションを行う場合、以下のように定義します。

public record Person(String name, int age) {
    public Person {
        if (age < 0) {
            throw new IllegalArgumentException("Age cannot be negative");
        }
    }
}

2. ネストされたRecordクラス

Recordクラスは、他のRecordクラスやクラス内にネストして定義することも可能です。

public record Address(String street, String city) {}

public record Person(String name, int age, Address address) {}

3. レコードのパターンマッチング

Java 16以降では、パターンマッチング と Recordクラスを組み合わせることで、より強力なデータ操作が可能になります。

public static String getName(Object obj) {
    if (obj instanceof Person(String name, int age)) {
        return name;
    }
    return "Unknown";
}

Recordクラスを利用すべきケース

✅ シンプルなデータキャリア

値を保持するだけのシンプルなクラスに最適です。従来のPOJOやDTOの代わりに利用することで、コードの冗長性を減らし、明確さを向上させます。

✅ 不変データの表現

Recordクラスはイミュータブルであるため、スレッドセーフな設計が求められる場合にも効果的です。

✅ 簡潔なデータ転送オブジェクト(DTO)

データ転送オブジェクト(DTO)として、外部とのデータ交換やAPIレスポンスの形式定義に使用することで、コードが簡潔になります。


実装時に気を付けるべき事項

🔴 不変性の理解

Recordクラスは**不変(イミュータブル)**であり、定義されたフィールドは変更できません。そのため、データが変更されることがないことを前提に設計する必要があります。

🔴 継承の制限

Recordクラスは、他のクラスを継承することができません。また、Recordクラス自体を継承することもできません。この制約を理解し、他のデザインパターンを利用する必要があります。

🔴 バリデーションの注意

Recordクラスでは、コンストラクタ内で引数のバリデーションを行うことができますが、複雑なロジックが必要な場合は、従来のクラスを使用する方が適切な場合もあります。

🔴 データサイズの管理

Recordクラスは簡潔にデータを表現できますが、大量のフィールドやデータを含める場合、適切なデータモデリングを行わないと、パフォーマンスに影響を及ぼす可能性があります。


公式ドキュメント

Recordクラスに関する詳細なリファレンスは、以下の公式ドキュメントを参照してください。


まとめ

JavaのRecordクラスは、データキャリアとしてのクラス定義を簡潔に行える強力なツールです。不変性を持ち、シンプルなデータを扱う場面で特に有効です。Recordクラスを適切に利用することで、コードの明確さと保守性を大幅に向上させることができます。

実装時の注意点を守りつつ、適切なケースで活用出来ると生産性が上がりそうです。

Discussion