Lombok 子类如何使用 @Builder
作者:jitwxs
https://jitwxs.cn/54621f54.html
一、前言
業務開發中,子類父類還算是經常用到,Lombok 的 @builder 提供的鏈式調用幫助我們更輕松的創建對象。但是實驗后卻發現子類的 @Builder 是不會包含父類的屬性。
假設存在父類 A:
@Data @Builder public?class?A?{private?String?aName;private?String?aAge; }存在子類 B:
@Builder @Data @EqualsAndHashCode(callSuper?=?true) public?class?B?extends?A?{private?String?bName;private?String?bAge; }使用 builder 進行初始化時,類 A 可以正常創建,類 B 僅可以初始化自己的屬性,父類屬性無法初始化。
二、解決:構造方法
查閱網絡后,一種解決方法是利用構造方法:
-
父類生成全參構造方法
-
子類手動聲明全參構造方法
-
將子類 @builder 注解移動全參構造方法上,并設置 builderMethodName
修改 Main 方法如下:
public?class?BuilderMain?{public?static?void?main(String[]?args)?{A?xxx?=?A.builder().aName("xxx").aAge("111").build();B?yyy?=?B.childBuilder().aName("xxx").aAge("111").bName("yyy").bAge("222").build();System.out.println(xxx);System.out.println(yyy);} }代碼運行后,能得到正確結果:
A(aName=xxx,?aAge=111) B(super=A(aName=xxx,?aAge=111),?bName=yyy,?bAge=222)但是這種方式弊端也很明顯:
-
子類調用父類的全參構造,當父類參數數量、順序調整時,子類也需要同步調整。
-
如果父類參數過多,構造方法十分不優雅。
三、解決:SuperBuilder
Lombok 自 v1.18.2 開始,為了解決這個問題,引入了 @SuperBuilder 注解,使用該注解,就可以很容易解決這個問題。
修改代碼如下:
@Data @SuperBuilder public?class?A?{private?String?aName;private?String?aAge; } @SuperBuilder @Data @EqualsAndHashCode(callSuper?=?true) @ToString(callSuper?=?true) public?class?B?extends?A?{private?String?bName;private?String?bAge; }Main 方法保持不變,代碼運行后,能得到正確結果:
A(aName=xxx,?aAge=111) B(super=A(aName=xxx,?aAge=111),?bName=yyy,?bAge=222)另外自 v1.18.4 也給 SuperBuilder 引入了toBuilder 參數,可以很方便的進行淺拷貝對象,效率雖然比手動 builder 慢一點,但也算是挺快的。
@Data @SuperBuilder(toBuilder?=?true) public?class?A?{private?String?aName;private?String?aAge; }給 B 加入屬性 C,測試對象拷貝:
@SuperBuilder(toBuilder?=?true) @Data @EqualsAndHashCode(callSuper?=?true) @ToString(callSuper?=?true) public?class?B?extends?A?{private?String?bName;private?String?bAge;private?C?c; }~
@AllArgsConstructor public?class?C?{private?String?name; }輸出結果如下:
public?class?BuilderMain?{public?static?void?main(String[]?args)?{B?b?=?B.builder().aName("xxx").aAge("111").bName("yyy").bAge("222").c(new?C("zhangsan")).build();System.out.println(b);System.out.println(b.toBuilder().build());} } B(super=A(aName=xxx,?aAge=111),?bName=yyy,?bAge=222,?c=com.github.jitwxs.demo.builder.C@52cc8049) B(super=A(aName=xxx,?aAge=111),?bName=yyy,?bAge=222,?c=com.github.jitwxs.demo.builder.C@52cc8049)四、彩蛋
由于 @SuperBuilder 剛引入不久,所以還是有一些 BUG 的,比如當你的 SpringBoot 版本為 2.2.3.RELEASE 時,或者你的 Lombok 版本低于 v1.18.12 時,使用上文的例子,你就會發現竟然無法通過編譯。
實際的原因是不支持用 B 來命名類,簡直是吐出一口老血,好在升級到 v1.18.12 版本后就修復了這個問題,可能這就是給不規范命名的人埋的坑吧,哈哈。
推薦文章-
今天給大家推薦 6 個 Spring Boot 項目,拿來就可以賺錢!
-
分享一套基于SpringBoot和Vue的企業級中后臺開源項目,這個項目有點哇塞!
-
圈子哥推薦一款基于 Spring Boot 開發 OA 開源產品,學習/搞外快都是不二選擇!
-
硬剛一周,3W字總結,一年的經驗告訴你如何準備校招!
總結
以上是生活随笔為你收集整理的Lombok 子类如何使用 @Builder的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 有了这篇网络排错思路大总结:我帮了不少同
- 下一篇: 新同事上来就把项目性能优化了一遍,瑟瑟发