lombok中的@Builder.Default注解为成员变量赋默认值
(1)只对成员变量设置默认值,builder构造默认值是无效的
@Data
@Builder
@AllArgsConstructor
@NoArgsConstructor
public class Student {
private Integer age = 2;
private String name;
}
如果我们用,java的new操作,是会对Student设置默认值的
Student s = new Student();
// Student(age=2, name=null)
但是Builder是无效的
Student s = Student.builder().build();
Student(age=null, name=null)
原因在于,编译生成的Student.class文件,保留了成员变量的初始值,但是在StuentBuilder中,只有成员变量,而没有默认值
//
// Source code recreated from a .class file by IntelliJ IDEA
// (powered by Fernflower decompiler)
//
import java.beans.ConstructorProperties;
import java.io.Serializable;
public class Student implements Serializable {
private Integer age = 2;
private String name;
@ConstructorProperties({"age", "name"})
Student(Integer age, String name) {
this.age = age;
this.name = name;
}
public static Student.StudentBuilder builder() {
return new Student.StudentBuilder();
}
public static class StudentBuilder {
private Integer age;
private String name;
StudentBuilder() {
}
public Student.StudentBuilder age(Integer age) {
this.age = age;
return this;
}
public Student.StudentBuilder name(String name) {
this.name = name;
return this;
}
public Student build() {
return new Student(this.age, this.name);
}
public String toString() {
return "Student.StudentBuilder(age=" + this.age + ", name=" + this.name + ")";
}
}
}
(2)设置@Builder.Default注解后,通过标识判断是否启用默认值
@Builder
public class Student implements Serializable {
@Builder.Default
private Integer age = 2;
private String name;
}
//
// Source code recreated from a .class file by IntelliJ IDEA
// (powered by Fernflower decompiler)
//
import java.beans.ConstructorProperties;
import java.io.Serializable;
public class Student implements Serializable {
private Integer age;
private String name;
private static Integer $default$age() {
return 2;
}
@ConstructorProperties({"age", "name"})
Student(Integer age, String name) {
this.age = age;
this.name = name;
}
public static Student.StudentBuilder builder() {
return new Student.StudentBuilder();
}
public static class StudentBuilder {
private boolean age$set;
private Integer age;
private String name;
StudentBuilder() {
}
public Student.StudentBuilder age(Integer age) {
this.age = age;
this.age$set = true;
return this;
}
public Student.StudentBuilder name(String name) {
this.name = name;
return this;
}
public Student build() {
return new Student(this.age$set ? this.age : Student.$default$age(), this.name);
}
public String toString() {
return "Student.StudentBuilder(age=" + this.age + ", name=" + this.name + ")";
}
}
}
可以看到编译生成的.class文件,没有对age设置默认值。所以new出现的对象肯定没有设置默认值。
其次,通过引入标识age$set
,判断是否启用默认值
public Student build() {
return new Student(this.age$set ? this.age : Student.$default$age(), this.name);
}
this.age$set
默认是false
,只有在
public Student.StudentBuilder age(Integer age) {
this.age = age;
this.age$set = true;
return this;
}
中才对其进行赋值为true
。
也就是说,如果不调用Student s = Student.builder().age(4).build();
,age$set
为false
,执行Student.$default$age()
方法,设置默认值。否则,获取this.age
。
。
【总结】
(1)不用@Builder.Default,为成员变量设置默认值,new出来的对象自带默认值
(2)启用@Builder.Default,new出来的对象为空对象,不带默认值
(3)启用@Builder.Default,不设置-> Student.builder().build()
,为默认值
(4)启用@Builder.Default,设置-> Student.builder().age(4).build()
,为设置的值
关键看Student.class
文件