Java实体类 @Data@NoArgsConstructor@AllArgsConstructor@ToString注解_allargsconstructor注解详解
在Java实体类中,@Data、@NoArgsConstructor、@AllArgsConstructor 和 @ToString 是 Lombok 提供的常用注解
注意事项
- Lombok 需要安装插件:IDE 中需要安装 Lombok 插件才能正确识别这些注解。
 - 编译时生成代码:这些注解是在编译时通过注解处理器生成代码,而不是运行时。
 - 不可见但存在:生成的代码在源代码中不可见,但编译后的字节码中包含。
 
一、介绍
1. @Data
- 作用:这是一个组合注解,相当于同时添加了以下注解:
 
2. @NoArgsConstructor
- 作用:生成一个无参的构造方法。
 - 适用场景:某些框架(如 Hibernate、MyBatis)需要实体类有一个无参构造方法。
 
3. @AllArgsConstructor
- 作用:生成一个包含所有字段的构造方法(按字段声明顺序)。
 - 注意:如果类中有 
final字段且未初始化,使用此注解可能会导致编译错误。 
4. @ToString
- 作用:生成 toString() 方法,默认格式为:
类名(字段名=字段值, 字段名=字段值...)。 - 常用参数:
exclude:排除某些字段of:只包含某些字段callSuper:是否包含父类的 toString() 结果
 
import lombok.*;@Data@NoArgsConstructor@AllArgsConstructor@ToStringpublic 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 反序列化(如 
Jackson、Gson)通常需要无参构造方法创建对象,再填充数据。 - 例如:
// 反序列化时,Jackson 会先调用无参构造方法,再通过 setter 填充数据User user = objectMapper.readValue(json, User.class); 
(3) Java Bean 规范
- 标准的 Java Bean 要求提供无参构造方法,以便工具和框架能动态创建实例。
 
2. 为什么要设置全参构造方法(@AllArgsConstructor)?
(1) 方便对象初始化
- 在手动创建对象时,可以直接传入所有参数,避免逐个调用 
setter:// 使用全参构造方法User user = new User(1L, \"张三\", 25);// 对比:没有全参构造方法时,需要逐个 setUser user = new User();user.setId(1L);user.setName(\"张三\");user.setAge(25); 
(2) 不可变对象(Immutable Objects)
- 如果字段是 
final的(不可变),就必须在构造方法中初始化,而不能用setter:@AllArgsConstructorpublic class User { private final Long id; // final 字段必须通过构造方法初始化 private final String name;} 
(3) 配合 @Builder 使用
- 如果使用 
@Builder(建造者模式),通常需要全参构造方法支持:@Builder@AllArgsConstructorpublic 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@AllArgsConstructor@ToStringtoString()@Data@Getter、@Setter、@ToString、@EqualsAndHashCode等)最佳实践
- 大多数情况下,可以直接用 
@Data,它已经包含了@ToString和@RequiredArgsConstructor(部分场景替代@AllArgsConstructor)。 - 如果涉及ORM框架,额外加上 
@NoArgsConstructor。 - 如果需要Builder模式,可以加 
@AllArgsConstructor和@Builder。 


