Java 16 新增了一项非常酷炫的特性,那就是 Record(记录)。
Record 可以让我们更方便地定义类,它简化了代码,并提供了类似于数据传输对象(DTO)和值对象(VO)的功能。在本文中,我将深入介绍 Java Record 的各种使用方法、使用场景、优点、缺点和注意事项。
简介
Record 是一个新的类声明,它结合了 final 类和不可变类型的特征。与普通类不同,Record 类不能扩展其他类,并且其成员变量默认为 final 和私有的,不允许对它们进行修改,这也意味着 Record 类不能有 setter 方法。Record 的状态是不可变的,而且是公共可读。
下面是一个简单的 Record 示例:
public record Person(String name, int age) {}
这个示例定义了一个名为 Person 的 Record 类,它有两个实例字段:name 和 age。
使用方法
Record 类提供了多种使用方法,以下是一些常用的方法:
创建 Record 类
我们可以使用 record
关键字创建 Record 类,定义方式与普通类类似。例如:
public record Person(String name, int age) {}
这个类有一个构造器,这种可以自动定义地设置所有实例字段的构造器称为 标准构造器。实现标准构造器的时候可以使用一种简洁的形式,即不需要制定参数列表。
Person(String name, int age)
record Person(String name, int age, String era) { Person { if (age > 0 && age <= 10) { era = "小孩"; } else if (age > 10 && age <= 20) { era = "少年"; } else if (age > 20 && age <= 30) { era = "青年"; } else { era = "中年"; } } } public static void main(String[] args) { Person person = new Person("张三", 20, ""); System.out.println(person.era); }
除了标准构造器,还可以定义自定义构造器,不过这种构造器的第一个语句必须调用另一个构造器。
创建对象
与普通类一样,我们可以使用 new 关键字创建 Record 对象。
Person person = new Person("Tom", 20);
访问实例字段
上面定义的记录会自动定义以下访问器方法:
public String name(); public int age();
注意,这些访问器方法名是 name 和 age,而不是 getName 和 getAge。
自动化生成方法
除了构造器、访问器方法,每个记录有三个自动定义的方法:toString、equals、hashCode。我们可以使用 @Override 注解重写这些方法。
record Person(String name, int age) { @Override public String toString() { return "Person{name='" + name + "', age=" + age + "}"; } }
自定义方法
record Person(String name, int age) { public String hello(String friend) { return "hello %s, my name is %s".formatted(friend, name); } } public static void main(String[] args) { Person person = new Person("张三", 23); System.out.println(person.hello("李四")); }
静态字段和静态方法
record Person(String name, int age) { public static String LOCATION = "北京"; public static String location() { return "location is %s".formatted(LOCATION); } } public static void main(String[] args) { System.out.println(Person.LOCATION); System.out.println(Person.location()); }
注意,不能为记录添加实例字段,比如下面的写法就是错误的!
record Person(String name, int age) { private String sex; }
使用场景
Record 类主要用于简单数据类型和值类型的表示,适合于以下场景:
- DTO 和 VO 对象:Record 类可以用于表示数据传输对象(DTO)和值对象(VO)。
- 数据库实体类:Record 类还可以用于表示数据库实体类。
- 不可变对象:由于 Record 类的成员变量是 final 的,我们无法修改它们的值,因此适合用于不可变对象。
优点
- 简化代码:Record 类减少了冗余代码,使代码更加简洁明了。
- 提高可读性:Record 类可以让代码更易读,因为它提供了自动生成的方法和清晰的语法。
- 更安全:由于 Record 类的成员变量是 final 的,它们不能被修改,从而提高了代码的安全性。
缺点
- 不支持继承:与普通类不同,Record 类不能扩展其他类,这可能限制。不过 Record 类可以实现接口。