皆さん、前回の記事でJavaの基本的なクラスについて学んだよね。
クラスとオブジェクトの概念 – オブジェクト指向の入り口 | ToolDocs
今回は、そんなクラスの中でも**「データだけをシンプルに扱いたい!」ってときに超便利なレコードクラス**について解説していくよ。
「え、データクラスって何?」って思った人もいるかもしれないね。簡単に言うと、名前とか年齢とか、**「いくつかの情報をひとまとまりとして扱いたい」**ときに使うのがデータクラス。例えば、ユーザー情報を扱うなら「ユーザーID」「ユーザー名」「メールアドレス」なんかをまとめて「ユーザー」ってひとつのクラスにしたいよね。
レコードクラスってなんだ?
Javaでデータクラスを作る時、今まではこんな感じで書いてたの覚えてるかな?
Java
class User {
private final int id;
private final String name;
private final String email;
public User(int id, String name, String email) {
this.id = id;
this.name = name;
this.email = email;
}
public int getId() {
return id;
}
public String getName() {
return name;
}
public String getEmail() {
return email;
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
User user = (User) o;
return id == user.id && name.equals(user.name) && email.equals(user.email);
}
@Override
public int hashCode() {
return Objects.hash(id, name, email);
}
@Override
public String toString() {
return "User{" +
"id=" + id +
", name='" + name + '\'' +
", email='" + email + '\'' +
'}';
}
}
どう?めちゃくちゃコード量が多いよね?こんなに書くのは大変だし、正直めんどくさい!
でも、Java 16から導入されたレコードクラスを使えば、これがびっくりするくらいシンプルになるんだ。レコードクラスは、主にデータを保持するためだけのクラスを、もっと簡単に書けるように作られた特別なクラスなんだ。
じゃあ、さっきのUserクラスをレコードクラスで書いてみよう。
Java
record User(int id, String name, String email) {
// コンストラクタやゲッターなどは自動で生成される!
}
見て!たった1行で書けちゃった!
レコードクラスを使うと、以下のものが自動で生成されるんだ。
- すべてのフィールドを引数に持つコンストラクタ
- 各フィールドのゲッターメソッド(
getId(),getName()のように、フィールド名と同じ名前のメソッドになる) equals()メソッド(オブジェクトの比較に使うやつね)hashCode()メソッド(ハッシュ値を計算するやつ)toString()メソッド(オブジェクトの中身を文字列で表示するやつ)
これらを自分で書く手間がなくなるから、コード量が大幅に減って、読みやすく、間違いも減るんだ。まさに**「データクラス作成の救世主」**って感じだよね!
レコードクラスを使ってみよう!
実際にレコードクラスを使ってみるよ。さっきのUserレコードを使ってみよう。
Java
public class RecordExample {
public static void main(String[] args) {
// Userレコードのインスタンスを作成
User user1 = new User(1, "森田", "morita@example.com");
// ゲッターを使ってデータにアクセス
System.out.println("ユーザーID: " + user1.id()); // getId()ではなく、id()と呼び出す
System.out.println("ユーザー名: " + user1.name());
System.out.println("メールアドレス: " + user1.email());
// toString()メソッドも自動で生成される
System.out.println("ユーザー情報: " + user1.toString());
// equals()メソッドで比較
User user2 = new User(1, "森田", "morita@example.com");
User user3 = new User(2, "佐藤", "sato@example.com");
System.out.println("user1とuser2は同じ?: " + user1.equals(user2)); // trueになる
System.out.println("user1とuser3は同じ?: " + user1.equals(user3)); // falseになる
}
}
// Userレコードの定義(同じファイル内に書いてもOK)
record User(int id, String name, String email) { }
出力結果はこんな感じになるよ。
ユーザーID: 1
ユーザー名: 森田
メールアドレス: morita@example.com
ユーザー情報: User[id=1, name=森田, email=morita@example.com]
user1とuser2は同じ?: true
user1とuser3は同じ?: false
どうかな?すごくシンプルに書けてるのがわかるよね!

paizaで実行した結果
レコードクラスのちょっと便利な使い方
レコードクラスは、基本的にデータを保持するだけなんだけど、ちょっとしたメソッドを追加することもできるんだ。
例えば、ユーザーのフルネームを返すメソッドを追加したい場合。
Java
record User(int id, String firstName, String lastName) {
// コンストラクタをカスタマイズすることもできるけど、基本は自動生成に任せよう
// 例えば、引数をチェックしたい場合など
public User {
if (firstName == null || firstName.isBlank()) {
throw new IllegalArgumentException("名前に不正な値が含まれています。");
}
if (lastName == null || lastName.isBlank()) {
throw new IllegalArgumentException("名前に不正な値が含まれています。");
}
}
// 新しいメソッドを追加できる
public String fullName() {
return firstName + " " + lastName;
}
}
public class RecordCustomMethodExample {
public static void main(String[] args) {
User user = new User(101, "太郎", "山田");
System.out.println("ユーザー名: " + user.fullName());
// コンストラクタのチェックも試してみる
try {
User invalidUser = new User(102, "", "田中");
} catch (IllegalArgumentException e) {
System.out.println("エラー: " + e.getMessage());
}
}
}
出力結果はこうなるよ。
ユーザー名: 太郎 山田
エラー: 名前に不正な値が含まれています。
こんな風に、レコードクラスに機能を追加することもできるんだ。ただし、あくまでデータを保持することがメインのクラスだから、複雑なロジックをたくさん追加するのは避けた方がいいよ。複雑な処理が必要なら、通常のクラスを使うことを検討しよう。

paizaで実行した結果
レコードクラスと従来のクラスの比較
ここで、レコードクラスと従来のクラスの比較をもう一度まとめてみよう。
| 特徴 | 従来のクラス | レコードクラス |
|---|---|---|
| 目的 | データの保持、振る舞い(メソッド)など、あらゆる用途 | 主にデータをシンプルに保持することに特化 |
| コード量 | コンストラクタ、ゲッター、equals、hashCode、toStringなど、手動で書く必要があり、コード量が多い | これらが自動生成されるため、非常に少ないコード量で済む |
| 可読性 | コード量が多く、データ構造を把握しにくい場合がある | データ構造がひと目で分かりやすく、可読性が高い |
| 不変性 | ミュータブル(変更可能)なクラスを書きやすい(もちろんイミュータブルにもできるけど手間がかかる) | デフォルトでイミュータブル(不変)であり、安全にデータを扱える |
| 拡張性 | 継承など、高い拡張性を持つ | 継承はできない(finalクラスとして扱われる) |
レコードクラスは、特に**「データの入れ物」**として使う場合に、その真価を発揮するんだ。例えば、データベースから取得したデータを一時的に保持したり、APIのレスポンスデータを表したり、他のメソッドに複数の値をまとめて渡したい場合などに、とっても便利だよ。
一方で、クラスに複雑なロジックや状態を持つ必要がある場合は、従来のクラスを選ぶべきだね。レコードクラスはあくまで「シンプルなデータ」を扱うためのツールだと覚えておこう。
どんな時にレコードクラスを使えばいいの?
- DTO (Data Transfer Object) として:異なる層間でデータをやり取りする際に、シンプルなデータ構造を定義したいとき。
- 一時的なデータ構造として:メソッド内で複数の値を一時的にまとめる必要があるとき。
- マップのキーとして:
equals()とhashCode()が自動生成されるため、HashMapなどのキーとして使いやすい。 - タプル(複数の要素をまとめたもの)の代わりとして:複数の値をまとめて返したい場合に、わざわざ新しいクラスを作る手間が省ける。
レコードクラスは、あなたのJavaプログラミングをより効率的で、より読みやすいものに変えてくれる強力なツールなんだ。ぜひ積極的に使ってみてね!
まとめ
今回はJavaのレコードクラスについて解説したよ。
- レコードクラスは、データをシンプルに保持するための特別なクラス
- 従来のクラスに比べて、コンストラクタ、ゲッター、
equals()、hashCode()、toString()が自動生成されるため、コード量が大幅に削減される - これにより、可読性が向上し、バグのリスクも減る
- 主にDTOや一時的なデータ構造など、**「データの入れ物」**として使うと便利
レコードクラスを使いこなして、もっと効率的にJavaプログラミングを楽しもう!
今回の記事で、レコードクラスの便利さが伝わったかな?もし疑問に思ったことや、もっと知りたいことがあったら、ぜひコメントで教えてね!


コメント