结论先行,阅读止步于此也可。java
@Builder
没法直接使用字段默认值@Default
,才可使用字段默认值@Builder
会自动生成一个全参的构造函数咱们有一个学生类(为了方便,咱们只使用1个字段。该字段带默认值)函数
@Builder
public class Student {
private int stuStatus = 1;
}
复制代码
经过观察编译以后的代码,经过Student$StudentBuilder.class
咱们能够知道@Builder
注解生成了一个StudentBuilder
的静态内部类。ui
将Student.class与Student$StudentBuilder.class反编译以后代码以下:this
public class Student {
private int stuStatus = 1;
// 注意此处:@Builder已经生成了一个全参构造函数。因此不能直接使用new Student()。若是想使用那么须要使用另外一个注解:@NoArgsConstructor
Student(int stuStatus) {
this.stuStatus = stuStatus;
}
public static StudentBuilder builder() {
return new StudentBuilder();
}
}
public class Student$StudentBuilder {
private int stuStatus;
public Student$StudentBuilder stuStatus(int stuStatus) {
this.stuStatus = stuStatus;
return this;
}
public Student build() {
return new Student(this.stuStatus);
}
public String toString() {
return "Student.StudentBuilder(stuStatus=" + this.stuStatus + ")";
}
}
复制代码
此时咱们执行以下代码:spa
Student student = Student.builder().build();
复制代码
此时student
的stuStatus
字段并非你所指望的1,而是0。缘由咱们经过上述Student$StudentBuilder
代码能够看出来:执行build()
方法的时候使用的静态内部类的stuStatus
,此时该字段为0。因此最终的student
的stuStatus
字段值为0。code
Q:如何才能使用stuStatus的默认值呢?
A: 为使用默认值的字段使用@Default注解(详细说明见下文)。cdn
在
Builder.java
中能够发现,@Builder
内部还有几个注解,此时咱们须要使用的就是@Default
注解blog
咱们有一个学生类(此时使用@Default
注解)string
@Builder
public class Student {
@Default
private int stuStatus = 1;
}
复制代码
将Student.class与Student$StudentBuilder.class反编译以后代码以下:it
public class Student {
private int stuStatus;
// 返回stuStatus的默认值1
private static int $default$stuStatus() {
return 1;
}
Student(int stuStatus) {
this.stuStatus = stuStatus;
}
public static StudentBuilder builder() {
return new StudentBuilder();
}
// $FF: synthetic method
static int access$000() {
return $default$stuStatus();
}
}
public class Student$StudentBuilder {
private boolean stuStatus$set;
private int stuStatus;
public Student$StudentBuilder stuStatus(int stuStatus) {
this.stuStatus = stuStatus;
this.stuStatus$set = true;
return this;
}
public Student build() {
int stuStatus = this.stuSstuStatustauts;
// 会判断stuStatus是否被显式的set,若是没有被set,则使用默认值。
if(!this.stuStatus$set) {
stuStatus = Student.access$000();
}
return new Student(stuStatus);
}
public String toString() {
return "Student.StudentBuilder(stuStatus=" + this.stuStatus + ")";
}
}
复制代码
此时咱们执行以下代码:
Student student = Student.builder().build();
复制代码
此时student
的stuStatus
字段就是你所指望的1。缘由:咱们经过上述Student$StudentBuilder
代码能够看出来:执行build()
方法的时候会判断程序是否设置了stuStatus
字段,若是没有设置(stuStatus$set是false)则调用Student.access$000()
(该方法便是获取字段默认值)为stuStatus赋值。
经过分析,明白了lombok为什么不能直接使用字段默认值了。可是至于lombok为什么这么作就不了解了。我给字段设置默认值的缘由就是想不为该字段赋值的时候,字段能直接使用默认值,可是lombok却直接忽略了默认值,而是额外须要@Default注解。