結論先行,閱讀止步於此也可。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註解。