1.前言
今天在看專案程式碼的時候, 遇到了實體類上加@Builder註解, 之前在開發的時候, 一直沒有用過這個註解, 便興致勃勃地去查了一下資料, 它也是Lombok中的註解, 我們都知道Lombok的註解是在java程式碼進行編譯時對程式碼進行構建. Lombok外掛的出現, 使得開發人員無需寫多餘的重複程式碼, 對於java物件的建立更是提供了Builder方法, 使得開發人員在設計實體類的時候, 對外保持private setter, 而對屬性的賦值採用Builder方式, 不對外公開屬性的寫操作, 這種方式更加優雅, 並且符合面向物件程式設計的封裝原則.
2.pom.xml的引入
1 <dependency>
2 <groupId>org.projectlombok</groupId>
3 <artifactId>lombok</artifactId>
4 <version>1.18.12</version>
5 </dependency>
3.@Builder註解的應用
1 /**
2 * @author lyh
3 * @version v-1.0.0
4 * @since 2021/6/3
5 */
6 public class TestBuilder {
7 public static void main(String[] args) {
8
9 // 使用Builder註解來建立一個User例項
10 User zs = User.builder()
11 .age(15)
12 .name("zs").build();
13 System.out.println(zs);
14
15 /**
16 * 修改原物件的屬性值
17 * 注意: 修改實體, 要在實體的@Builder註解裡面設定toBuilder = true
18 * toBuilder的預設值是false,這個可以自行去檢視@Builder註解類的實現
19 * 裡面有這樣一行程式碼:
20 * boolean toBuilder() default false;
21 */
22 zs = zs.toBuilder()
23 .age(18).build();
24 System.out.println(zs);
25
26 }
27 }
28
29 輸出:
30 User(name=zs, age=15)
31 User(name=zs, age=18)
32
33 Process finished with exit code 0
1 @Builder
2 @Getter
3 @ToString
4 public class User {
5
6 private String name;
7
8 private Integer age;
9
10 }
4.@Builder內部工作
先來看一下使用@Builder註解之後, User類編譯後的程式碼:
1 public class User {
2 private String name;
3 private Integer age;
4
5 User(String name, Integer age) {
6 this.name = name;
7 this.age = age;
8 }
9
10 public static User.UserBuilder builder() {
11 return new User.UserBuilder();
12 }
13
14 public String getName() {
15 return this.name;
16 }
17
18 public Integer getAge() {
19 return this.age;
20 }
21
22 public String toString() {
23 return "User(name=" + this.getName() + ", age=" + this.getAge() + ")";
24 }
25
26 public static class UserBuilder {
27 private String name;
28 private Integer age;
29
30 UserBuilder() {
31 }
32
33 public User.UserBuilder name(String name) {
34 this.name = name;
35 return this;
36 }
37
38 public User.UserBuilder age(Integer age) {
39 this.age = age;
40 return this;
41 }
42
43 public User build() {
44 return new User(this.name, this.age);
45 }
46
47 public String toString() {
48 return "User.UserBuilder(name=" + this.name + ", age=" + this.age + ")";
49 }
50 }
51 }
通過上面編譯後的User類程式碼可以看到@Builder的內部工作結果:
建立了一個名為UserBuilder的靜態內部類, 並且具有和實體類相同的屬性(稱為構建器).
在構建器中: 對於目標類中的所有的屬性, 都會在構建器中建立對應的屬性.
在構建器中: 建立一個無參的default構造方法.
在構建器中: 對於實體類中的每個引數, 都會對應建立類似於setter方法, 但是方法名是與該引數名是相同的, 並且返回值是構建器本身(便於鏈式呼叫).
在構建器中: 一個build方法, 呼叫此方法, 就會根據設定的值進行建立物件例項.
在構建器中: 同時也會生成一個toString() 方法.
在構建器中: 會建立一個builder()方法, 它的目的是用來建立構建器.