使用Lombok@Builder、@Data(没有生成无参构造方法)这个坑要注意,,使用@Builder时配合@NoArgsConstructor和@AllArgsConstructor一起使用
Lombok为我们开发带来了极大便利,特别是在想要使用建造者模式的时候只需要在类上加@Builder注解即可。但是不小心也会引发隐藏的bug。
我们来看看案例
在维护旧代码的时候,由于以前创建类的时候是使用普通的new + 一系列的set方法去构建
需要构建的类如下,属性有缩减
@Data
public class SearchCondition {
private String years;
private List<String> months;
private String area;
private String province;
private String cityLevel;
}
由于参数众多,为了提高可维护性,打算使用造者模式模式去构建对象。在类对象前加@Builder
注解即可
使用如下
public static void main(String[] args) {
SearchCondition.builder()
.year(2021)
.months(new ArrayList<String>())
.area("华南")
.province("广东")
.build();
}
看起来没什么问题,编译也没问题,所以就没管了,但是在实际测试过程中,发现其他地方也有用到该类,由于使用@Builder
, 编译后的类的构造方法是如下的
可以看到是没有默认的无参构造方法,即使是加了@Data
注解也没有生成。我们在平时使用的时候直接new对象是编译会直接报错的
这其实也没什么影响,但是我们自己封装的一个工具类封装了一个copy方法,就是将一个类的属性赋值给另一个类,并创建另一个类。在创建那个类的时候使用的是反射
SearchCondition.class.newInstance();
而newInstance()
只会调用类的无参构造方法,这就比较坑了,而编译又不会报错,所以只有在使用的时候才会报错。
解决方式也很简单,就是自己添加无参构造函数
SearchCondition() {
}
需要注意的是如果自己添加了无参构造函数,我们使用的@Builder
则不会给我们添加一个全参的构造函数,所以我们还需要添加全参的构造方法,不然也会报错
SearchCondition(Integer year, List<String> months, String area, String province, String cityLevel) {
this.year = year;
this.months = months;
this.area = area;
this.province = province;
this.cityLevel = cityLevel;
}
这样就解决了,所以在使用@Builder
注解时候一定要注意是否有该类会通过反射构建。