Menu
CoddyTech

记录类(Java 16+)

本课属于 Coddy Java 学习旅程的“面向对象编程”单元。第 51 课,共 87 课。

创建用于携带数据的简单类时,你常常要编写重复的样板代码:私有字段、构造函数、getter、toString()、equals() 和 hashCode()。Java 16 引入了记录类,以省去这些繁琐的工作。

record 是一种特殊的类,专门用于保存不可变数据。你可以使用 record 关键字,后面跟着组件列表来声明它:

record Person(String name, int age) { }

// 这一行代码会自动提供:
// -私有的 final 字段:name 和 age
// -构造方法:Person(String name, int age)
// -访问器方法:name() 和 age()
// -toString()、equals() 和 hashCode()

使用记录很简单:

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]

请注意,访问器方法不使用 get 前缀:它们直接以字段命名。记录类会隐式声明为 final,因此不能被继承。所有字段也都是 final,因此记录类天然不可变。

你可以根据需要添加自定义方法,并重写自动生成的方法。你还可以在紧凑构造函数中添加验证:

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

记录非常适合用于 DTO、API 响应,或任何需要简单、不可变数据容器,又不想编写样板代码的场景。

challenge icon

挑战

简单

让我们构建一个电影票预订系统,展示 Java record 的简洁之美。你将看到,record 可以省去样板代码,同时仍允许你添加自定义方法和验证逻辑。

你需要将代码分为三个文件:

  • Movie.java:创建一个表示电影的 record,包含三个组件:title(String)、genre(String)和 durationMinutes(int)。添加一个名为 getFormattedDuration() 的自定义方法,以易读的格式返回时长:[hours]h [minutes]m(例如,142 分钟会变成 2h 22m)。使用整数除法和取模运算计算小时数和剩余分钟数。
  • Ticket.java:创建一个表示电影票的 record,包含三个组件:movie(Movie)、seatNumber(String)和 price(double)。添加一个紧凑构造函数来验证票价,如果票价小于或等于零,就抛出带有消息 Price must be positive 的 IllegalArgumentException。再添加一个名为 printTicket() 的自定义方法,返回一个多行字符串:
    ========== TICKET ==========
    Movie: [movie title]
    Genre: [movie genre]
    Duration: [formatted duration from movie]
    Seat: [seatNumber]
    Price: $[price]
    ============================
  • Main.java:将预订系统组合起来!你会收到五个输入:电影标题(String)、类型(String)、时长(分钟,int)、座位号(String)和票价(double)。

    使用前三个输入创建一个 Movie record,然后使用电影、座位号和票价创建一个 Ticket record。打印对 ticket 调用 printTicket() 的结果。

你会依次收到五个输入:电影标题、类型、时长(分钟)、座位号和票价。

注意,与传统类相比,record 简洁了许多:不需要编写构造函数、getter、toString()、equals() 或 hashCode()。紧凑构造函数让你无需重复赋值字段就能添加验证逻辑,而且你仍然可以按需添加自定义方法!

亲手试试

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:使用电影、seatNumber 和 price 创建 Ticket 记录
        
        // TODO:使用 printTicket() 方法打印票据
        
    }
}
quiz icon自我测试

这节课包含一个小测验。开始学习即可作答,并记录你的进度。

面向对象编程中的所有课

自己练习: Java 在线编译器