一行代码胜千言,Java Record让我告别了无尽的getter和setter!
还记得那些年被JavaBean支配的恐惧吗?作为一个资深Java开发者,我曾经每天都要写这样的代码:
// 传统的JavaBean
public class User {
private String name;
private String email;
private int age;
public User() {}
public User(String name, String email, int age) {
this.name = name;
this.email = email;
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
User user = (User) o;
return age == user.age &&
Objects.equals(name, user.name) &&
Objects.equals(email, user.email);
}
@Override
public int hashCode() {
return Objects.hash(name, email, age);
}
@Override
public String toString() {
return "User{" +
"name='" + name + ''' +
", email='" + email + ''' +
", age=" + age +
'}';
}
}
整整57行代码!只是为了存储3个字段的数据!
目前,让我展示Java Record的魔法:
// Java Record版本
public record User(String name, String email, int age) {}
是的,你没看错,只有1行代码!
为什么Record如此强劲?
1. 自动实现所有样板代码
这一行Record声明相当于自动为你生成了:
- final类和final字段
- 规范构造函数
- 所有字段的getter方法(注意:不是getXxx(),而是直接字段名)
- equals()、hashCode()、toString()方法
使用起来极其简洁:
// 创建实例
User user = new User("张三", "zhangsan@email.com", 25);
// 自动生成的getter(直接使用字段名,不加get前缀)
System.out.println(user.name()); // 输出:张三
System.out.println(user.email()); // 输出:zhangsan@email.com
System.out.println(user.age()); // 输出:25
// 自动生成的toString()
System.out.println(user);
// 输出:User[name=张三, email=zhangsan@email.com, age=25]
// 自动生成的equals()和hashCode()
User user2 = new User("张三", "zhangsan@email.com", 25);
System.out.println(user.equals(user2)); // 输出:true
2. 数据比较的终极解决方案
以前我们比较两个数据对象需要写一大堆代码:
// 传统方式比较两个用户是否一样
public boolean isSameUser(User user1, User user2) {
return user1 != null && user2 != null &&
Objects.equals(user1.getName(), user2.getName()) &&
Objects.equals(user1.getEmail(), user2.getEmail()) &&
user1.getAge() == user2.getAge();
}
目前只需要:
// Record方式
public boolean isSameUser(User user1, User user2) {
return user1 != null && user1.equals(user2);
}
// 或者更简单,直接使用equals
user1.equals(user2);
3. 完美适合DTO、VO等数据传输对象
场景一:API响应对象
// 传统方式 - 至少50+行代码
public class ApiResponse<T> {
private boolean success;
private String message;
private T data;
private long timestamp;
// 构造函数、getter、setter、equals、hashCode、toString...
}
// Record方式 - 1行搞定!
public record ApiResponse<T>(boolean success, String message, T data, long timestamp) {}
// 使用
ApiResponse<User> response = new ApiResponse<>(
true, "查询成功", user, System.currentTimeMillis()
);
场景二:数据库查询结果映射
// 传统方式
public class UserDTO {
private String userName;
private String email;
private String departmentName;
private LocalDateTime createTime;
// ... 又是一大堆样板代码
}
// Record方式
public record UserDTO(String userName, String email,
String departmentName, LocalDateTime createTime) {}
// 在Spring Data JPA中的使用
public interface UserRepository extends JpaRepository<User, Long> {
// 直接返回Record
@Query("SELECT new com.example.UserDTO(u.name, u.email, d.name, u.createTime) " +
"FROM User u JOIN u.department d WHERE u.id = :id")
UserDTO findUserDTOById(@Param("id") Long id);
}
4. 模式匹配的完美搭档
Java 14引入的instanceof模式匹配与Record配合天衣无缝:
// 处理不同类型的消息
public interface Message {}
public record TextMessage(String content, String sender) implements Message {}
public record ImageMessage(String url, int width, int height) implements Message {}
public record FileMessage(String fileName, byte[] content) implements Message {}
// 使用模式匹配进行处理
public void processMessage(Message message) {
if (message instanceof TextMessage textMsg) {
System.out.println("文本消息: " + textMsg.content() + " 来自: " + textMsg.sender());
} else if (message instanceof ImageMessage imgMsg) {
System.out.println("图片消息: " + imgMsg.url() + " 尺寸: " + imgMsg.width() + "x" + imgMsg.height());
} else if (message instanceof FileMessage fileMsg) {
System.out.println("文件消息: " + fileMsg.fileName() + " 大小: " + fileMsg.content().length);
}
}
5. 自定义构造器和验证
Record也支持自定义行为:
public record User(String name, String email, int age) {
// 简洁构造函数,可用于数据验证
public User {
if (age < 0) {
throw new IllegalArgumentException("年龄不能为负数");
}
if (email == null || !email.contains("@")) {
throw new IllegalArgumentException("邮箱格式不正确");
}
// 这里还可以对数据进行处理,列如去除空格
name = name != null ? name.trim() : null;
}
// 自定义方法
public boolean isAdult() {
return age >= 18;
}
public String displayInfo() {
return name + " (" + email + ")";
}
}
// 使用
User user = new User(" 李四 ", "lisi@email.com", 20);
System.out.println(user.isAdult()); // 输出:true
System.out.println(user.displayInfo()); // 输出:李四 (lisi@email.com)
实战案例:重构前后对比
重构前:传统的命令模式实现
// 命令接口
public interface Command {
void execute();
}
// 具体命令类 - 每个都要写一大堆样板代码
public class CreateUserCommand implements Command {
private String username;
private String email;
private String password;
public CreateUserCommand(String username, String email, String password) {
this.username = username;
this.email = email;
this.password = password;
}
// 又是一堆getter...
public String getUsername() { return username; }
public String getEmail() { return email; }
public String getPassword() { return password; }
@Override
public void execute() {
// 创建用户的业务逻辑
System.out.println("创建用户: " + username);
}
// 别忘了equals、hashCode、toString...
}
重构后:使用Record
// 命令接口
public interface Command {
void execute();
}
// 具体命令类 - 一行搞定!
public record CreateUserCommand(String username, String email, String password) implements Command {
@Override
public void execute() {
// 创建用户的业务逻辑
System.out.println("创建用户: " + username);
}
}
// 还可以轻松创建更多命令
public record UpdateUserCommand(Long userId, String username, String email) implements Command {
@Override
public void execute() {
System.out.println("更新用户: " + userId);
}
}
public record DeleteUserCommand(Long userId) implements Command {
@Override
public void execute() {
System.out.println("删除用户: " + userId);
}
}
什么时候不适合使用Record?
Record不是万能的,以下情况提议使用传统类:
- 需要可变状态(Record是不可变的)
- 需要继承其他类(Record是final的)
- 需要精细控制序列化过程
- 需要复杂的业务逻辑和状态变更
总结
Java Record带来的效率提升是实实在在的:
- 代码量减少80%+ – 从几十行到一行
- bug率大幅下降 – 自动实现的equals/hashCode避免人为错误
- 可读性极大提升 – 声明即文档
- 维护成本降低 – 添加字段只需修改一处
自从在项目中全面采用Record,我的开发效率至少提升了一倍,再也不用在getter、setter、equals、hashCode上浪费时间。代码更简洁,bug更少,心情更好!
记住这个公式:更少代码 = 更少bug = 更高效率
是时候让你的Java代码来一次彻底升级了!
© 版权声明
文章版权归作者所有,未经允许请勿转载。

受益匪浅👏
收藏了,感谢分享
有点像政治课,避重就轻
学 c#
大神💪
学到了💪
真不戳💪
这个厉害了👏