问题的历史:
Record类(record)在Java 14中作为预览功能出现,从Java 16版本开始,这是一个稳定的功能。它们实现了用于存储数据的不可变(immutable)容器的概念,类似于值对象(value-objects)。这是对Java中经典DTO和POJO冗长的反应。
问题:
对于简单的数据对象,必须手动实现构造函数、equals()、hashCode()、toString()。这是一项繁琐且容易出错的工作,需占用大量代码行。
解决方案:
Record类只需一行声明,并自动获得构造函数、getter、equals()、hashCode()、toString()。record的字段是不可变的(final),record尤其适合在应用程序的不同层之间传递信息。
代码示例:
public record Point(int x, int y) {} Point p = new Point(3, 5); System.out.println(p.x()); // 3 System.out.println(p); // Point[x=3, y=5]
主要特点:
是否可以在创建record后更改对象的状态?
不可以——所有字段都是final,无法以任何方式更改值。
是否可以在构造函数中创建具有非标准逻辑的record?
可以,您可以定义紧凑或普通构造函数并添加检查:
public record Point(int x, int y) { public Point { if (x < 0 || y < 0) throw new IllegalArgumentException(); } } }
record是否可以是抽象的,或者继承其他类的字段/逻辑?
不可以——record总是final。可以实现接口,但不能继承类,除了Object。
为每个请求/响应使用长POJO,手动编写equals、hashCode、toString、构造函数和getter。
优点:
缺点:
将所有DTO转换为record类:
public record UserDTO(String login, String email) {}
优点:
缺点: