Java 中的 DTO 与 Record:有啥区别,具体如何选择?
Java 中的 DTO 与 Record:什么是 Java Record?

目前我们已经了解了 DTO 和 Record,接下来在这一节中进行比较。
(1)不可变性
Record 默认是不可变的,这意味着一旦创建了一个 Record 实例,你就无法更改其数据。这种不可变性确保了数据的一致性和线程安全性,无需额外的代码。例如,在一个 UserRecord 中,字段 name、age 和 email 只能在创建 Record 时设置,之后无法修改。
另一方面,DTO 一般是可变的,这意味着它们的字段可以在对象创建后更改。要使 DTO 不可变,你需要明确避免使用 setter 或精心设计它们(例如,使用 final 字段)。以下是 Record 与传统 DTO 在不可变性方面的对比:
- Record:默认不可变。
- DTO:需要手动强制实现不可变性,这可能导致代码更加复杂并引发潜在的错误。
public class ImmutabilityExample {
public static void main(String[] args) {
UserDTO userDTO = new UserDTO("xxx", 25, "xxx@example.com");
userDTO.setAge(26); // DTO allows this by default.
UserRecord userRecord = new UserRecord("xxx", 25, "xxx@example.com");
userRecord.name = "Jane"; // This would result in a compile-time error.
}
}
(2)数据表明
Record 提供了一种 简洁且紧凑 的数据表明方式。由于 Record 的声明只包含字段,代码更加清晰易读。这使得在拥有大量数据模型的项目中维护代码变得更加容易。
例如:
// Record:简洁明了
public record UserRecord(String name, int age, String email) {}
与之相比,DTO 一般包含更多的代码:
// DTO:更加冗长
public class UserDTO {
private String name;
private int age;
private String email;
// 构造函数、Getter、Setter、toString、equals、hashCode...
}
使用 Record,意图更加明确:它只是一个数据载体,没有额外的行为,而 DTO 则容易被样板代码或额外逻辑所充斥。
(3)定制化
在定制化方面,DTO 有必定的优势。DTO 允许你添加自定义逻辑,例如数据验证、转换方法,甚至在需要时添加业务逻辑(尽管在纯 DTO 中一般不推荐)。例如,你可以添加一个验证方法来确保电子邮件字段符合有效格式。
而 Record 的自定义能力则较为有限。由于它们被设计为轻量级且不可变的,因此你无法轻松地添加修改内部状态或执行复杂逻辑的自定义方法。如果你的用例需要在数据对象中包含自定义行为或逻辑,DTO 提供了更多的灵活性。
以下是一个在 DTO 中添加自定义验证的示例:
public class UserDTO {
private String email;
// 验证电子邮件格式的方法
public boolean isValidEmail() {
return email != null && email.contains("@");
}
}
对于 Record,这种级别的自定义一般需要在 Record 之外进行处理。Record 专注于携带数据,而像验证这样的逻辑一般需要在其他地方处理。
(4)与函数式编程的一致性
函数式编程的一个核心原则是不可变性——即数据对象在创建后不应被修改。Record 更加符合函数式编程的原则,由于它们默认是不可变的。这使得它们成为采用或倾向于函数式编程风格的系统的理想选择。
Record:
- 被设计为不可变的,这与函数式编程强调创建不可变数据结构的理念相一致。
- 它们促进了更具声明性的风格,你可以传递不可变的数据对象,而不会产生副作用,这使得它们更加可预测且易于理解。
相比之下,DTO 本质上是可变的。尽管可以通过避免使用 setter 和使用 final 字段来使 DTO 不可变,但这需要手动强制执行。DTO 一般遵循 面向对象 的范式,其中状态变化更为常见。
DTO:
- 在可变性方面更加灵活,这使得它们更适合命令式或面向对象的编程风格。
- 当以可变形式使用时,DTO 可能会导致副作用,这在函数式编程中一般是不被推荐的。
#夏日生活打卡季##上头条 聊热点##java##record##Java##JDK#
















- 最新
- 最热
只看作者