レコード

編集

Java 16でrecord型が追加された[1]。レコードは、インスタンス作成時に一度だけ値を設定し、後から変更しないための仕組みである。

クラスを使って同様の動作を実装することも可能だが、record型を使うことでコードが短くなり、意図も明確になるなどの利点がある。

コード例
sample.java
class Sample {
    public static void main(String[] args) {
        record Person(String name, int age) {}

        // Personオブジェクトの作成
        Person tom = new Person("Tom", 13);
        Person john = new Person("John", 15);

        // 情報の出力
        System.out.printf("名前: %s, 年齢: %d%n", tom.name(), tom.age());
        System.out.printf("名前: %s, 年齢: %d%n", john.name(), john.age());
    }
}
実行結果
名前: Tom, 年齢: 13 
名前: John, 年齢: 15
レコード定義
record Person(String name, int age) {}

は、次の標準クラスと同等です:

public final class Person {
    private final String name;
    private final int age;

    public Person(String name, int age) {
        this.name = name;
        this.age = age;
    }

    String name() { return this.name; }
    int age()  { return this.age; }

    // equals() と hashCode() を実装し、2つのレコードオブジェクトが同じ型であり、
    // 同じフィールド値を持つ場合、等しいことを指定する。
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;
        Person person = (Person) o;
        return age == person.age && name.equals(person.name);
    }

    public int hashCode() {
        return Objects.hash(name, age);
    }

    // toString() は、レコードクラスのすべてのフィールドの名前とその値の文字列表現を返す。
    public String toString() {
        return String.format("Person[name=%s, age=%d]", name, age);
    }
}

インスタンス作成時には、final var a のように final 修飾子を付ける必要はない。record型のインスタンスは自動的に final となり、変更できなくなる。

なお、final var a = new Person("Tom", 13); のように final を付けても正常に動作し、結果は変わらない。

脚註

編集
  1. ^ Record (Java SE 16 & JDK 16)” (2021年7月20日). 2022年7月1日閲覧。