【发布时间】:2021-09-19 15:42:55
【问题描述】:
我在 IntelliJ 中的 Spring Boot 应用程序上在线看到了多个代码,许多代码同时使用 @AllArgsConstructor 和 @NoArgsConstructor 并且两者都是构造函数,但是每个的目的是不同的 -
-
@AllArgsConstructor为注释类中的每个字段生成一个需要参数的构造函数 -
@NoArgsConstructor生成一个没有参数的构造函数
那我们为什么要在同一个实体上同时使用两者?在这种情况下它们如何发挥作用?
@Data
@AllArgsConstructor
@NoArgsConstructor
@ToString
@Entity
public class Product {
@Id
private int id;
private String name;
private String type;
}
【问题讨论】:
-
实体中需要一个默认构造函数(没有任何参数的构造函数)。这是必需的,因为 JPA/Hibernate 使用默认构造函数方法来使用反射创建 bean 类。如果您不指定任何构造函数(也没有指定 Lombok 注解),Java 将生成一个默认构造函数(如果没有为该类定义构造函数,则由编译器自动生成)。但是如果你添加一个带参数的构造函数(或
@AllArgsConstructor),那么你还需要添加一个无参数构造函数(或@NoArgsConstructor),JPA/Hibernate 才能工作。 -
@Yann39 好的,我明白了。现在,我宣布
@AllArgsConstructor。但是为什么 JPA 不能在不声明@NoArgsConstuctor的情况下工作呢? -
因为只有在没有为类定义构造函数的情况下,Java 才会生成默认构造函数。一旦定义了一个,它就不会生成无参数构造函数。另请注意,您正在使用
@Data,它捆绑了@RequiredArgsConstructor的功能,它将为所有最终或@NonNull注释字段生成构造函数。因此,由于您只使用非最终可为空的字段,因此即使您不添加@NoArgsConstructor,它也可能会生成一个空构造函数。不过,我还没有测试过最后一个案例。 -
好的,现在明白了,谢谢
-
好。我发表评论是因为我现在没有时间写一个干净的答案,但我可以稍后发布更详细的答案。
标签: spring-boot jpa constructor lombok intellij-plugin