聊聊@Accessors和@Builder
目录
@Accessors和@Builder
@Accessors(chain=true)
就是new一个对象后可以链式调用set给属性赋值。
@Data
@Accessors(chain = true)
public class User {
private String name;
private Integer age;
private Double weight;
public static void main(String[] args) {
User user = new User().setName("张三").setAge(18).setWeight(60.00);
System.out.println(user);
}
}
从上面的代码我们看到new User()
后面可以链式调用set方法赋值。
这是因为@Accessors(chain=true)
将lombok生成的setter方法返回值变为了this
,也就是返回了对象本身,代替了原本的void。
@Builder
@Builer
注解是基于建造者模式的链式操作。
@Data
@Builder
public class User {
private String name;
private Integer age;
private Double weight;
public static void main(String[] args) {
User user = User.builder().name("张三").age(18).weight(60.00).build();
System.out.println(user);
}
}
我们能看到是先使用bulder
方法后再链式操作,然后调用build
方法返回。
原因是内部生成了构建起UserBuilder
,调用builder()
方法就是是创建UserBuilder
对象,然后给UserBuilder
对象赋值,最后通过UserBuilder
对象的build()
来生成User
对象。
可以看编译后的class文件
@Accessors和@Builder的区别
其实我们看它们编译后的class文件就可以直到原因。@Accessors
是将生成的setter()
方法返回this
,而@Builder
是再对象内部创建一个构建器,通过这个构建器来最终创建对象。
@Builder
底层新建了一个对象,为了实现链式调用再创建一个对象感觉优点大材小用了。
@Accessors
再实现了链式调用的基础上,减少了多余对象的创建。
@Accessors和@Builder使用的坑
- 在有的开源反射工具包对对象进行浅拷贝时,获取set方法原信息时会判断返回值是否为void,这样使用
@Accessors
注解就会报错。 -
@Builder
注解会给类默认生成全参构造,这样就没有了默认的无参构造,在Spring这类容器中默认调用无参构造就报错了,所以要加上@NoArgsConstructor
和@AllArgsConstructor
注解
详细看看@Accessors注解
@Accessors的源码
可以看到它有四个属性,chian=true
就是可以链式调用,其他的下面我们来分别说明下。
@Accessors属性说明
fluent属性
fluent=true
时,setter和getter方法就没有set和get了,直接调用属性名即可
chain属性
chain=true
时,就可以链式调用setter方法给属性赋值了
makeFinal属性
makeFinal=true
时,生成的setter和getter方法都是final修饰的方法
final修饰的方法表示不能在子类中重写这些方法。
prefix属性
该属性添加一个数据,添加属性的前缀,表示忽略属性对应的前缀来生成setter和getter方法
如上图一样,属性赋值的时候就可以忽略前缀。
prefix属性的坑
1、如果属性的前缀和prefix写的前缀不匹配,那setter和getter方法就不会生成了。
2、属性的前缀后的第一个字母必须是大写,否则也不会生成setter和getter方法。
3、上面说的不会生成setter和getter方法是连不去前缀的都不会生成,相当于@Data注解失效了。