はじめに
Javaでプログラムを書いていると、ファイルから読み込んだ1行分のデータ、DBから取得した1件分のデータ、APIから受け取った1件分のデータなどを、ひとまとまりのオブジェクトとして扱いたい場面がよくある。
従来は class を作り、フィールド、コンストラクタ、getter / setter を用意していたが、どうしても記述量が多くなってしまう。
そこで Java 16 から正式導入されたのが record だ。
record基礎
まずは、実際に見てみよう
public record Person(String name,int age){}従来は単なるデータの持ち運びのためだけにも以下のようなクラスを作成する必要があった。
recordの記述がいかに短いのかがわかるであろう。
public class Person {
private String name;
private int age;
public Person(String name, int age) {
this.name = name;
this.age = age;
}
public String getName() {
return this.name;
}
public int getAge() {
return this.age;
}
}インスタンスの作成
実際にrecordからインスタンスを作成してみよう。
Person p = new Person("山田",23);コンストラクタが暗黙に実装されるため、従来のクラスと同じようにインスタンスを作成できる。
データの取得
データは以下のように取得できる
System.out.println(p.name());//山田
System.out.println(p.age());//23この際、p.getName()のような従来のgetterと違い、getがつかないことがポイントとなる
recordの特徴
イミュータブル
まず、大きな特徴がイミュータブルであるということだ。
データは内部的にprivate final フィールドになっているため、値の再代入を行なうことはできない。
以下のような記述はいずれもコンパイルエラーとなる
p.name="田中";
p.setName("田中");toStirng(),equals(),hashCode()
record では toString()、equals()、hashCode() が自動的に実装されるため、以下のようなことが可能になる。
Person p1 = new Person("山田", 20);
Person p2 = new Person("山田", 20);
System.out.println(p1);//Person[name=Taro, age=20]
System.out.println(p1.equals(p2));//true通常のclassはtoStringをオーバーライドしないと、
Person@5acf9800
のように
クラス名@ハッシュコード
が出力されるが、recordでは
Person[name=Taro, age=20]
のフォーマットで出力される。
また、equalsでの比較もrecordではデータ項目の値がすべて等しければtrueを返す
メソッド
recordにはメソッドを実装することもできる
public record Person(String name,int age){
public void showInfo(){
System.out.println(name + "さんは" + age + "歳です。");
}
public boolean isAdult(){
return age > 18;
}
}Person p = new Person("山田",20);
p.showInfo();
if(p.isAdult()){
処理
}ただし、recordはデータを表すための型なので、複雑な処理を多く持たせるよりも、保持している値を使った簡単な計算や表示用メソッドにとどめるのが自然だ。
record利用例
実際に動く形での例を示す。
import java.util.ArrayList;
import java.util.List;
public class RecordApp {
public static void main(String[] args) {
List<Person> list = new ArrayList<>();
list.add(new Person("山田",20));
list.add(new Person("田中",23));
System.out.println(list.get(0).name());//山田
}
}
record Person(String name,int age) {}recordを使うことによってシンプルに記述ができることがわかる
最後に
Javaのバージョンがあがるときに仕組みが追加されていくが、なかには使いやすさに疑問を感じることも多い。
しかし、このrecordはとても使いやすく、初めて使用したときから大のお気に入りとなった。
ファイルから1行ずつ読み込んでDBに格納したり、APIからJSON取得してインスタンスを生成したり…そのような機会は多いがこのrecordは負担軽減に大いに役立つであろう。

コメント