<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

          Lombok 子類如何使用 @Builder

          共 3723字,需瀏覽 8分鐘

           ·

          2021-01-17 13:40

          點擊上方?好好學java?,選擇?星標?公眾號

          重磅資訊、干貨,第一時間送達

          今日推薦:分享一套基于SpringBoot和Vue的企業(yè)級中后臺開源項目,這個項目有點哇塞!

          個人原創(chuàng)100W+訪問量博客:點擊前往,查看更多

          作者:jitwxs

          https://jitwxs.cn/54621f54.html

          一、前言

          業(yè)務(wù)開發(fā)中,子類父類還算是經(jīng)常用到,Lombok 的 @builder 提供的鏈式調(diào)用幫助我們更輕松的創(chuàng)建對象。但是實驗后卻發(fā)現(xiàn)子類的 @Builder 是不會包含父類的屬性。

          假設(shè)存在父類 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 可以正常創(chuàng)建,類 B 僅可以初始化自己的屬性,父類屬性無法初始化。

          二、解決:構(gòu)造方法

          查閱網(wǎng)絡(luò)后,一種解決方法是利用構(gòu)造方法:

          • 父類生成全參構(gòu)造方法
          • 子類手動聲明全參構(gòu)造方法
          • 將子類 @builder 注解移動全參構(gòu)造方法上,并設(shè)置 builderMethodName
          @Data
          @Builder
          @NoArgsConstructor
          @AllArgsConstructor
          public?class?A?{
          ????private?String?aName;

          ????private?String?aAge;
          }


          @Data
          @EqualsAndHashCode(callSuper?=?true)
          @ToString(callSuper?=?true)
          public?class?B?extends?A?{
          ????private?String?bName;

          ????private?String?bAge;

          ????@Builder(builderMethodName?=?"childBuilder")
          ????public?B(String?aName,?String?aAge,?String?bName,?String?bAge)?{
          ????????super(aName,?aAge);
          ????????this.bName?=?bName;
          ????????this.bAge?=?bAge;
          ????}
          }

          修改 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);
          ????}
          }

          代碼運行后,能得到正確結(jié)果:

          A(aName=xxx,?aAge=111)
          B(super=A(aName=xxx,?aAge=111),?bName=yyy,?bAge=222)

          但是這種方式弊端也很明顯:

          • 子類調(diào)用父類的全參構(gòu)造,當父類參數(shù)數(shù)量、順序調(diào)整時,子類也需要同步調(diào)整。
          • 如果父類參數(shù)過多,構(gòu)造方法十分不優(yōu)雅。

          三、解決: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 方法保持不變,代碼運行后,能得到正確結(jié)果:

          A(aName=xxx,?aAge=111)
          B(super=A(aName=xxx,?aAge=111),?bName=yyy,?bAge=222)

          另外自 v1.18.4 也給 SuperBuilder 引入了toBuilder 參數(shù),可以很方便的進行淺拷貝對象,效率雖然比手動 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;
          }

          輸出結(jié)果如下:

          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 時,使用上文的例子,你就會發(fā)現(xiàn)竟然無法通過編譯。

          實際的原因是不支持用 B 來命名類,簡直是吐出一口老血,好在升級到 v1.18.12 版本后就修復了這個問題,可能這就是給不規(guī)范命名的人埋的坑吧,哈哈。

          推薦文章

          原創(chuàng)電子書

          歷時整整一年總結(jié)的?Java 面試 + Java 后端技術(shù)學習指南,這是本人這幾年及校招的總結(jié),各種高頻面試題已經(jīng)全部進行總結(jié),按照章節(jié)復習即可,已經(jīng)拿到了大廠offer。

          原創(chuàng)思維導圖

          掃碼或者微信搜?程序員的技術(shù)圈子?回復?面試?領(lǐng)取原創(chuàng)電子書和思維導圖。

          瀏覽 64
          點贊
          評論
          收藏
          分享

          手機掃一掃分享

          分享
          舉報
          評論
          圖片
          表情
          推薦
          點贊
          評論
          收藏
          分享

          手機掃一掃分享

          分享
          舉報
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  美女扒开尿口让男人捅爽 | 影音先锋在线视频免费观看 | 岛国免费播放器无码 | 国产片精品一区在线播放 | av毛片网 |