レコード (Java 16+)
CoddyのJavaジャーニー「オブジェクト指向プログラミング」セクションの一部。レッスン 51/87。
単純なデータを保持するクラスを作成するとき、private フィールド、constructor、getter、toString()、equals()、hashCode()といった定型コードを繰り返し記述することがよくあります。Java 16では、この退屈な作業をなくすためにレコードが導入されました。
record は、不変データを保持するために設計された特別な class です。コンポーネントリストの後に record キーワードを続けて記述して宣言します。
record Person(String name, int age) { }
// その単一行が自動的に提供するもの:
// - private final フィールド: name と age
// - コンストラクタ: Person(String name, int age)
// - アクセサメソッド: name() と age()
// - toString()、equals()、および hashCode()record の使用は簡単です:
Person p = new Person("Alice", 30);
System.out.println(p.name()); // Alice
System.out.println(p.age()); // 30
System.out.println(p); // Person[name=Alice, age=30]accessor methods は get プレフィックスを使用しないことに注目してください。fields にちなんで単純に命名されています。レコードは暗黙的に final であるため、拡張できません。すべての fields も final であり、レコードは本質的に不変です。
custom methods を追加し、必要に応じて自動生成されたものをオーバーライドできます。また、compact constructor に検証を追加することもできます:
record Person(String name, int age) {
public Person {
if (age < 0) throw new IllegalArgumentException("Age cannot be negative");
}
}Recordは、DTOやAPIレスポンス、またはボイラープレートコードを書かずにシンプルで不変のデータコンテナが必要なあらゆる場面に最適です。
チャレンジ
簡単Java レコードの洗練さを示す映画チケット予約システムを構築しましょう。レコードによって定型コードをなくしながら、custom なメソッドや検証を追加できることがわかります。
コードを3つのファイルに分けて構成します。
Movie.java:映画を表すレコードを Create します。3つの components、title(String)、genre(String)、durationMinutes(int)を持たせます。getFormattedDuration()という custom メソッドを Add し、duration をわかりやすい形式で返します:[hours]h [minutes]m(たとえば、142分は2h 22mになります)。integer division と modulo を使用して、hours と残りの minutes を計算します。Ticket.java:映画チケットを表すレコードを Create します。3つの components、movie(Movie)、seatNumber(String)、price(double)を持たせます。price を検証する compact constructor を Add し、price が zero 以下の場合は、messagePrice must be positiveとともにIllegalArgumentExceptionを throw します。また、printTicket()という custom method も Add し、複数行の string を返します。========== TICKET ========== Movie: [movie title] Genre: [movie genre] Duration: [formatted duration from movie] Seat: [seatNumber] Price: $[price] ============================Main.java:予約システムを完成させます!5つの inputs、つまり映画のタイトル(String)、genre(String)、分単位の duration(int)、座席番号(String)、チケット価格(double)を受け取ります。最初の3つの inputs で Movie record を Create し、次に movie、座席番号、price で Ticket record を Create します。ticket に対して
printTicket()を呼び出した結果を出力します。
inputs は順番に5つ受け取ります:映画のタイトル、genre、duration(minutes)、座席番号、price。
従来のクラスと比べて、レコードがどれほどすっきりしているかに注目してください。constructor、getter、toString()、equals()、hashCode() を記述する必要がありません。compact constructor を使えば、fields への代入を繰り返さずに検証を Add できます。また、必要に応じて custom methods も Add できます。
自分で試してみよう
import java.util.Scanner;
class Main {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
// 入力を読み取る
String title = scanner.nextLine();
String genre = scanner.nextLine();
int durationMinutes = Integer.parseInt(scanner.nextLine());
String seatNumber = scanner.nextLine();
double price = Double.parseDouble(scanner.nextLine());
// TODO: title、genre、durationMinutesを持つMovieレコードを作成する
// TODO: movie、seatNumber、priceを持つTicketレコードを作成する
// TODO: printTicket()メソッドを使用してチケットを出力する
}
}
このレッスンには短いクイズがあります。レッスンを始めて解答し、進捗を記録しましょう。
オブジェクト指向プログラミングのすべてのレッスン
4継承
継承の基本 (extends)super キーワードメソッドのオーバーライド (@Override)コンストラクタチェーンObject クラス単一継承と多段階継承なぜ多重継承ができないのかまとめ:従業員の階層構造自分で練習してみよう: Javaオンラインコンパイラ