1.使用范围
- 类:作用在类上,生成构造器
2.介绍
@Builder 注解为类生成相对略微复杂的构建器 API
它作用于类,将其变成建造者模式
可以以链的形式调用
初始化实例对象生成的对象是不可以变的,可以在创建对象的时候进行赋值
如果需要在原来的基础上修改可以加 set 方法,final 字段可以不需要初始化
它会生成一个全参的构造函数
3.属性
- @Builder.Default:非 final 的字段可以有默认值
- builderMethodName:指定创建内部静态类的方法名,默认值为 builder
- buildMethodName:指定创建实体类的方法名,默认值为 build
- builderClassName:指定内部静态的类名,默认值为 “”,默认创建的类名为 thisclassBuilder
- toBuilder:设置为 true 可以对这个对象进行拷贝生成新的对象,可以再修改,默认为 false
- access:设置 builderMethodName 的访问权限修饰符,默认为 public
共有 PUBLIC、MODULE、PROTECTED、PACKAGE、PRIVATE,其中 MODULE 是 Java 9 的新特性
- setterPrefix:设置 setter 方法的前缀,默认为 “”
4.实例
@Builder(
builderMethodName = "builder", buildMethodName = "build", builderClassName = "",
toBuilder = true, access = AccessLevel.PUBLIC, setterPrefix = ""
)
public class 刘亦菲 {
@Builder.Default
private String name = "刘亦菲";
private String sex;
private final Integer age = 18; // final 字段加不加 Default 都可以初始化成功
public static void main(String[] args) {
刘亦菲 yifei = 刘亦菲.builder().build(); // 如果没有加 Default,那么输出的 name 结果是 null。
/**
* 类似于拷贝,修改了 name 值,age 值还是原来的
* 如果 toBuilder = false,则没有 toBuilder 方法
*/
yifei = yifei.toBuilder().name("刘亦菲").build();
}
}
5.特殊注意
我们在平时开发中经常会用到泛型,而 @Builder 也支持指定泛型构建
@Builder
public class 刘亦菲<T> {
public void yiyang(刘亦菲<T> yi) {
yi = 刘亦菲.<T>builder().builder();
}
}
@Builder 会生成一个全参构造方法,因此就没有了无参构造方法,但当我们遇到需要无参构造方法时就会发生问题,这个时候手写或者加上 @NoArgsConstructor 都会报错,两种解决方案
- 同时使用NoArgsConstructor 和 AllArgsConstructor
- 使用@Tolerate注解
@Builder
@AllArgsConstructor
public class 刘亦菲 {
public 刘亦菲() {
/**
* 手写或者 @NoArgsConstructor 都会使 @Builder 生成的全参构造函数失效
* 这个时候就被报错,加上 @AllArgsConstructor 或者手写一个全参构造函数即可
*/
}
}
@Builder.ObtainVia
介绍:表示变量从什么地方获取值,只有当 toBuilder = true 时才生效
属性:
field:表示字段赋值时从某个字段上取值,对应的字段必须存在
method:表示字段赋值时从某个方法上取值,对应的方法必须存在
isStatic:表示 method 是否静态
从属性中取值:
@Builder(toBuilder = true)
public class 吴宣仪 {
private String name;
@Builder.ObtainVia(field = "name") // 对应变量 name,变量类型必须一样
private String identity;
public static void main(String[] args) {
吴宣仪 xunYi = 吴宣仪.builder().name("吴宣仪").build();
xunYi = xunYi.toBuilder().build(); // 此时 identity 为 name 变量值
System.out.println(xuanYi);
}
}
从方法中取值:
@Builder(toBuilder = true)
public class Rita {
private String name;
@Builder.ObtainVia(method = "init") // 对应方法 init,方法返回类型和字段类型必须统一
private String identity;
private String init() {
return "Rita";
}
public static void main(String[] args) {
Rita rita = Rita.builder().name("Rita").build();
rita = rita.toBuilder().build(); // 此时变量 identity 从 init 方法中取值
System.out.println(rita);
}
}