为什么要在实体类上同时使用@AllArgsConstructor与@NoArgsConstructor注解
两个注解同时使用的原因
@AllArgsConstructor和@NoArgsConstructor都是Lombok提供的编译期生成构造方法的注解,在Spring Boot项目的实体类中同时标注,是为了同时满足框架运行约束和业务编码的便利性需求,两个构造方法的不可替代性分别如下:
- @NoArgsConstructor生成的无参构造是框架运行的必需依赖
- JPA规范强制要求实体类必须提供无参构造方法,Hibernate等ORM框架在将数据库查询结果映射为实体对象时,会优先通过反射调用无参构造实例化空对象,再逐一给字段赋值,缺少无参构造会直接抛出运行时异常。
- JSON序列化、反序列化场景(比如Spring MVC接收前端JSON参数、Redis缓存对象序列化)中,Jackson、Gson等序列化框架默认也是通过无参构造创建目标对象,没有无参构造会触发反序列化失败的问题。
- 其他常用工具如Spring的
BeanUtils、Apache的PropertyUtils等属性拷贝工具,同样依赖无参构造预先创建目标对象。
- @AllArgsConstructor生成的全参构造是编码效率的优化
- 业务代码手动创建实体对象时,直接调用全参构造可以避免逐行调用set方法赋值,代码更简洁易读,比如示例中的
Product类可以直接通过new Product(1, "MacBook", "电子产品")完成实例化。 - 如果项目中配合使用
@Builder注解实现构建者模式,全参构造是@Builder正常运行的前置依赖,缺少全参构造会导致编译报错。
- 业务代码手动创建实体对象时,直接调用全参构造可以避免逐行调用set方法赋值,代码更简洁易读,比如示例中的
二者的运行逻辑
两个注解均为编译期生效,不会影响运行时性能:
- 编译.java文件时,Lombok会自动在生成的.class字节码中插入对应的无参、全参构造方法,和开发者手动编写的构造方法完全等效,没有额外的运行时逻辑。
- 两个构造方法同时存在时不会互相冲突,框架和业务代码会根据场景自动选择调用:ORM框架、序列化框架自动调用无参构造,业务编码时可以按需选择全参构造或者无参构造+set方法的方式实例化对象。
注意:如果实体类中存在
final修饰的字段,需要给@NoArgsConstructor添加force = true属性,Lombok会自动给final字段赋默认初始值(0、null、false等),避免编译报错。
代码示例
@Data @AllArgsConstructor @NoArgsConstructor @ToString @Entity public class Product { @Id private int id; private String name; private String type; }
内容的提问来源于stack exchange,提问作者NIKITA RATH
相关产品推荐
相关产品推荐

