代码示例
@Data
@Builder
@NoArgsConstructor
public static class User{
private String name;
private String code;
}
问题表现
[ERROR] User.java:[21,5] 无法将类User中的构造器 User应用到给定类型;
[ERROR] 需要: 没有参数
[ERROR] 找到: java.lang.String,java.lang.String
[ERROR] 原因: 实际参数列表和形式参数列表长度不同
解决方案
方案一:只使用 @Builder,不用new的构造函数
方案二:添加@AllArgsConstructor 来生成全参构造函数
问题分析
刚刚说了解决方案,不过内在问题还是要继续分析的,如果对Lombok了解较少的话,可以看下这篇文章:Lombok_江上一小白的博客-CSDN博客
@Builder 与 @NoArgsConstructor
@Builder:Builder 使用创建者模式又叫生成器模式(Builder Pattern),编译后生成生成 TBuilder一个名为 的内部类,其中包含一个私有全参构造函数,以及相应参数数量的静态方法。
@NoArgsConstructor:生成一个无参构造方法。
问题定位
@Builder 与 @NoArgsConstructor 冲突的直接问题是在编译的时候没有生成 Builder 所需要的私有全参构造函数,从而出现实际参数列表和形式参数列表长度不同的问题。
追溯到Lombok源码中,HandleBuilder 是 @Builder的处理类
// 生成构造函数
new HandleConstructor().generateConstructor(tdParent, AccessLevel.PACKAGE, allFields, null, SkipIfConstructorExists.I_AM_BUILDER, null,
Collections.<Annotation>emptyList(), annotationNode);
@Builder 注解在处理私有构造函数生成流程中,调用HandleConstructor进行构造函数生成。会判断是否存在其他的构造参数注解,如果有,则跳过构造函数的生成;如果没有,则会生成 Builder 需要的构造函数。