聊聊使用lombok @Builder踩到的坑


前言

什么是lombok

Lombok項目是一個Java庫,它會自動插入編輯器和構建工具中,Lombok提供了一組有用的注釋,用來消除Java類中的大量樣板代碼。

對lombok不熟悉的朋友,可以閱讀一下官方文檔,再來看本文。官方文檔如下

https://projectlombok.org/

正文

我們先來看一個小例子


提問: main函數會輸出什么?

答案:空指針異常

Exception in thread "main" java.lang.NullPointerException
	at com.github.lybgeek.msg.test.User.addPositionList(User.java:25)
	at com.github.lybgeek.msg.test.User.main(User.java:30)

回答出正確答案的朋友,下文基本上可以不用看了。可能有些朋友會有疑問,我例子中明明使用了

  private List<String> positionList = new ArrayList<>();

為什么還會報空指針?

真相就在lombok用@builder生成的class文件中,我們看下使用@builder,生成的class文件反編譯后長啥樣


看到我圈紅起來的,大家應該就一目了然。原來當我們用

 User user = User.builder().username("張三").build();

時,此時user對象中的positionList就會被userBuilder中的positionList覆蓋,而userBuilder中的positionList是null

如何解決

方法一:positionList前面加上final修飾

  private final List<String> positionList = new ArrayList<>();

此時用@Budiler生成class為

此時user對象中的positionList用的還是原先的positionList,因此不會出現空指針異常

方法二:positionList前面加上@Builder.Default注解

 @Builder.Default
 private List<String> positionList = new ArrayList<>();

此時用@Budiler生成class為

 public static class UserBuilder {
        private String username;
        private boolean positionList$set;
        private List<String> positionList;

        UserBuilder() {
        }

        public User.UserBuilder username(final String username) {
            this.username = username;
            return this;
        }

        public User.UserBuilder positionList(final List<String> positionList) {
            this.positionList = positionList;
            this.positionList$set = true;
            return this;
        }

        public User build() {
            List<String> positionList = this.positionList;
            if (!this.positionList$set) {
                positionList = User.$default$positionList();
            }

            return new User(this.username, positionList);
        }

當positionList$set為false,會給userBuilder的positionList賦值為

User.$default$positionList();
即:
  private static List<String> $default$positionList() {
        return new ArrayList();
    }

因此當user對象中的positionList被userBuilder中的positionList覆蓋后,userBuilder中的positionList是new ArrayList(),此時就不會出現空指針現象

方法三:不用build實例化對象

 User user = User.builder().username("張三").build();

改成用

User user = new User();
user.setUsername("張三");
user.addPositionList("經理");

總結

很多時候沒那么多的想當然


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM