Java实体类 @Data@NoArgsConstructor@AllArgsConstructor@ToString注解

本文章已经生成可运行项目,

在Java实体类中,@Data@NoArgsConstructor@AllArgsConstructor 和 @ToString 是 Lombok 提供的常用注解

注意事项

  1. Lombok 需要安装插件‌:IDE 中需要安装 Lombok 插件才能正确识别这些注解。
  2. 编译时生成代码‌:这些注解是在编译时通过注解处理器生成代码,而不是运行时。
  3. 不可见但存在‌:生成的代码在源代码中不可见,但编译后的字节码中包含。

一、介绍

1. @Data

  • 作用‌:这是一个组合注解,相当于同时添加了以下注解:
    • @Getter:为所有字段生成 getter 方法
    • @Setter:为所有非 final 字段生成 setter 方法
    • @ToString:生成 toString() 方法
    • @EqualsAndHashCode:生成 equals() 和 hashCode() 方法
    • @RequiredArgsConstructor:为所有 final 字段或标记为 @NonNull 的字段生成构造方法

2. @NoArgsConstructor

  • 作用‌:生成一个无参的构造方法。
  • 适用场景‌:某些框架(如 Hibernate、MyBatis)需要实体类有一个无参构造方法。

3. @AllArgsConstructor

  • 作用‌:生成一个包含所有字段的构造方法(按字段声明顺序)。
  • 注意‌:如果类中有 final 字段且未初始化,使用此注解可能会导致编译错误。

4. @ToString

  • 作用‌:生成 toString() 方法,默认格式为:类名(字段名=字段值, 字段名=字段值...)
  • 常用参数‌:
    • exclude:排除某些字段
    • of:只包含某些字段
    • callSuper:是否包含父类的 toString() 结果
import lombok.*;

@Data
@NoArgsConstructor
@AllArgsConstructor
@ToString
public class User {
    private Long id;
    private String name;
    private Integer age;
}

 对比一下上面的,下面为等效的传统Java代码:

public class User {
    private Long id;
    private String name;
    private Integer age;

    // @NoArgsConstructor
    public User() {}

    // @AllArgsConstructor
    public User(Long id, String name, Integer age) {
        this.id = id;
        this.name = name;
        this.age = age;
    }

    // @ToString
    @Override
    public String toString() {
        return "User(id=" + id + ", name=" + name + ", age=" + age + ")";
    }

    // @Data 生成的 getter/setter
    public Long getId() { return id; }
    public void setId(Long id) { this.id = id; }
    public String getName() { return name; }
    public void setName(String name) { this.name = name; }
    public Integer getAge() { return age; }
    public void setAge(Integer age) { this.age = age; }

    // @Data 生成的 equals 和 hashCode
    @Override
    public boolean equals(Object o) { /* 省略实现 */ }
    @Override
    public int hashCode() { /* 省略实现 */ }
}

是不是清楚了一些? 

二、为什么要用这些

在Java实体类中设置‌无参构造方法‌、‌有参构造方法‌和‌toString()方法‌,主要是为了满足‌编程规范‌、‌框架兼容性‌和‌开发便利性‌的需求。

1. 为什么要设置无参构造方法(@NoArgsConstructor)?

(1) 框架反射依赖

  • Hibernate、MyBatis、Spring Data JPA‌ 等ORM框架在‌从数据库查询数据并映射到对象‌时,通常需要‌先调用无参构造方法创建对象‌,再通过反射设置字段值。
  • 如果没有无参构造方法,这些框架可能会报错。

(2) 序列化/反序列化需求

  • JSON/XML 反序列化‌(如 JacksonGson)通常需要无参构造方法创建对象,再填充数据。
  • 例如:
    // 反序列化时,Jackson 会先调用无参构造方法,再通过 setter 填充数据
    User user = objectMapper.readValue(json, User.class);
    

(3) Java Bean 规范

  • 标准的 Java Bean 要求提供‌无参构造方法‌,以便工具和框架能动态创建实例。

2. 为什么要设置全参构造方法(@AllArgsConstructor)?

(1) 方便对象初始化

  • 在‌手动创建对象‌时,可以直接传入所有参数,避免逐个调用 setter
    // 使用全参构造方法
    User user = new User(1L, "张三", 25);
    
    // 对比:没有全参构造方法时,需要逐个 set
    User user = new User();
    user.setId(1L);
    user.setName("张三");
    user.setAge(25);
    

(2) 不可变对象(Immutable Objects)

  • 如果字段是 final 的(不可变),就必须在构造方法中初始化,而不能用 setter
    @AllArgsConstructor
    public class User {
        private final Long id;  // final 字段必须通过构造方法初始化
        private final String name;
    }
    

(3) 配合 @Builder 使用

  • 如果使用 @Builder(建造者模式),通常需要全参构造方法支持:
    @Builder
    @AllArgsConstructor
    public class User {
        private Long id;
        private String name;
    }
    

3. 为什么要重写 toString() 方法(@ToString)?

(1) 调试和日志输出

  • 默认的 Object.toString() 返回的是 类名@哈希码(如 User@1a2b3c),对调试毫无帮助。
  • 重写后,可以直观地看到对象内容:
    User user = new User(1L, "张三", 25);
    System.out.println(user);  // 输出:User(id=1, name=张三, age=25)
    

(2) 日志记录

  • 在日志中打印对象时,toString() 能提供更友好的信息:
    log.info("用户信息:{}", user);  // 输出:用户信息:User(id=1, name=张三, age=25)
    

(3) 避免手动拼接字符串

  • 如果没有 @ToString,每次打印对象都要手动拼接字段:
    // 没有 @ToString 时,需要手动拼接
    System.out.println("User(id=" + user.getId() + ", name=" + user.getName() + ")");
    

‌做一个小总结‌

注解作用适用场景
@NoArgsConstructor生成无参构造方法ORM框架(Hibernate/MyBatis)、反序列化(JSON/XML)
@AllArgsConstructor生成全参构造方法快速初始化对象、不可变对象、Builder模式
@ToString生成 toString()调试、日志打印、避免手动拼接字符串
@Data组合注解(包含@Getter@Setter@ToString@EqualsAndHashCode等)简化POJO类代码

最佳实践

  • 大多数情况下‌,可以直接用 @Data,它已经包含了 @ToString 和 @RequiredArgsConstructor(部分场景替代 @AllArgsConstructor)。
  • 如果涉及ORM框架‌,额外加上 @NoArgsConstructor
  • 如果需要Builder模式‌,可以加 @AllArgsConstructor 和 @Builder
本文章已经生成可运行项目
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值