迷茫了,我們到底該不該用lombok?

Python實戰社羣

Java實戰社羣

長按識別下方二維碼,按需求添加

掃碼關注添加客服

進Python社羣▲

掃碼關注添加客服

進Java社羣

作者丨因爲熱愛所以堅持ing

來源丨蘇三說技術

前言

最近上網查資料發現很多人對lombok褒貶不一,引起了我的興趣,因爲我們項目中也在大量使用lombok,大家不同的觀點讓我也困惑了幾天,今天結合我實際的項目經驗,說說我的個人建議。

隨便搜搜就找到了這幾篇文章:

這些人建議使用 lombok,覺得它是一個神器,可以大大提高編碼效率,並且讓代碼更優雅。

在搜索的過程中,有些文章卻又不推薦使用:

這些人覺得它有一些坑,容易給項目埋下隱患,我們到底該聽誰的呢?

爲什麼建議使用lombok?

1.傳統javabean

在沒使用lombok之前,我們一般是這樣定義javabean的:

public class User {

    private Long id;
    private String name;
    private Integer age;
    private String address;

    public User() {

    }

    public User(Long id, String name, Integer age, String address) {
        this.id = id;
        this.name = name;
        this.age = age;
        this.address = address;
    }

    public Long getId() {
        return id;
    }

    public String getName() {
        return name;
    }

    public Integer getAge() {
        return age;
    }

    public String getAddress() {
        return address;
    }


    public void setId(Long id) {
        this.id = id;
    }

    public void setName(String name) {
        this.name = name;
    }

    public void setAge(Integer age) {
        this.age = age;
    }

    public void setAddress(String address) {
        this.address = address;
    }

    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;
        User user = (User) o;
        return Objects.equals(id, user.id) &&
                Objects.equals(name, user.name) &&
                Objects.equals(age, user.age) &&
                Objects.equals(address, user.address);
    }

    @Override
    public int hashCode() {
        return Objects.hash(id, name, age, address);
    }

    @Override
    public String toString() {
        return "User{" +
                "id=" + id +
                ", name='" + name + '\'' +
                ", age=" + age +
                ", address='" + address + '\'' +
                '}';
    }
}

User類中包含了:成員變量、getter/setter方法、構造方法、equals、hashCode方法。

咋一看,代碼還是挺多的。而且還有個問題,如果User類中的代碼修改了,比如:age字段改成字符串類型,或者name字段名稱修改了,是不是需要同步修改相關的成員變量、getter/setter方法、構造方法、equals、hashCode方法全都修改一遍?

也許有些朋友會說:現在的idea非常智能,可以把修改一次性搞定。

沒錯,但是有更優雅的處理方法。

2.lombok的使用

第一步,引入jar包

  <dependency>
      <groupId>org.projectlombok</groupId>
      <artifactId>lombok</artifactId>
      <version>1.18.4</version>
      <scope>provided</scope>
  </dependency>

第二步,在idea中安裝插件

注意:如果不按照插件idea中就無法編譯使用lombok註解的代碼。

第三步,在代碼中使用lombok註解

上面的User類代碼可以改成這樣:

@ToString
@EqualsAndHashCode
@NoArgsConstructor
@AllArgsConstructor
@Getter
@Setter
public class User {

    private Long id;
    private String name;
    private Integer age;
    private String address;
}

so good,代碼可以優化到如此簡單。User類的主體只用定義成員變量,其他的方法全都交給註解來完成。

如果修改了成員變量名稱或者類型,怎麼辦呢?

@ToString
@EqualsAndHashCode
@NoArgsConstructor
@AllArgsConstructor
@Getter
@Setter
public class User {

    private Long id;
    private String userName;
    private String age;
    private String address;
}

你只用一心一意修改成員變量即可,其他的根本不用操心,簡直太爽了。

更讓人興奮的是,還能進一步優化:

@NoArgsConstructor
@AllArgsConstructor
@Data
public class User {

    private Long id;
    private String userName;
    private String age;
    private String address;
}

@Data相當於@Getter、@Setter、@ToString、@EqualsAndHashCode、@RequiredArgsConstructor的集合。

lombok註解整理如下:

圖片來源佔小狼

從上面看出使用lombok給人最大的感受是代碼量顯著減少了,能夠有效的提升開發效率,而代碼看起來更優雅,確實是一個不可多得的神器。

lombok工作原理

java程序的解析分爲:運行時解析編譯時解析

通常我們通過反射獲取類、方法、註解和成員變量就是運行時解析。但是這種方式效率其實不高,要在程序運行起來才能解析。

這時候編譯時解析就體現出它的價值了。

編譯時解析又分爲:註解處理器(Annotation Processing Tool)JSR 269 插入式註解處理器(Pluggable Annotation Processing API)

第一種處理器它最早是在 JDK 1.5 與註解(Annotation) 一起引入的,它是一個命令行工具,能夠提供構建時基於源代碼對程序結構的讀取功能,能夠通過運行註解處理器來生成新的中間文件,進而影響編譯過程。

不過在JDK 1.8以後,第一種處理器被淘汰了,取而代之的是第二種處理器,我們一起看看它的處理流程:

Lombok的底層具體實現流程如下:

  1. javac對源代碼進行分析,生成了一棵抽象語法樹(AST)

  2. 編譯過程中調用實現了“JSR 269 API”的Lombok程序

  3. 此時Lombok就對第一步驟得到的AST進行處理,找到@Data註解所在類對應的語法樹(AST),然後修改該語法樹(AST),增加getter和setter方法定義的相應樹節點

  4. javac使用修改後的抽象語法樹(AST)生成字節碼文件,即給class增加新的節點(代碼塊)

爲什麼建議不用lombok?

即使lombok是一個神器,但是卻有很多人不建議使用,這又是爲什麼呢?

1.強制要求隊友安裝idea插件

這點確實比較噁心,因爲如果使用lombok註解編寫代碼,就要求參與開發的所有人都必須安裝idea的lombok插件,否則代碼編譯出錯。

2.代碼可讀性變差

使用lombok註解之後,最後生成的代碼你其實是看不到的,你能看到的是代碼被修改之前的樣子。如果要想查看某個getter或setter方法的引用過程,是非常困難的。

3.升級JDK對功能有影響

有人把JDK從Java 8升級到Java 11時,我發現Lombok不能正常工作了。

4.有一些坑

  1. 使用@Data時會默認使用@EqualsAndHashCode(callSuper=false),這時候生成的equals()方法只會比較子類的屬性,不會考慮從父類繼承的屬性,無論父類屬性訪問權限是否開放。

  2. 使用@Builder時要加上@AllArgsConstructor,否則可能會報錯。

5.不便於調試

我們平時大部分人都喜歡用debug調試定位問題,但是使用lombok生成的代碼不太好調試。

6.上下游系統強依賴

如果上游系統中提供的fegin client使用了lombok,那麼下游系統必須也使用lombok,否則會報錯,上下游系統構成了強依賴。

我們該如何選擇?

lombok有利有弊,我們該如何選擇呢?

個人建議要結合項目的實際情況做最合理的選擇。

  1. 如果你參與的是一個新項目,上下游系統都是新的,這時候建議使用lombok,因爲它可以顯著提升開發效率。

  2. 如果你參與的是一個老項目,並且以前沒有使用過lombok,建議你後面也不要使用,因爲代碼改造成本較高。如果以前使用過lombok,建議你後面也使用,因爲代碼改造成本較高。

  3. 其實只要引入jar包可能都有:強制要求隊友安裝idea插件、升級JDK對功能有影響、有一些坑 和 上下游系統強依賴 這幾個問題,只要制定好規範,多總結使用經驗這些問題不大。

  4. 代碼的可讀性變差 和 不便於調試 這兩個問題,我認爲也不大,因爲lombok一般被使用在javabean上,該類的邏輯相對來說比較簡單,很多代碼一眼就能看明白,即使不調試問題原因也能猜測7、8分。

程序員專欄 掃碼關注填加客服 長按識別下方二維碼進羣

近期精彩內容推薦:  

 肝了一晚上搞出來一個微信訂閱號鑑黃機器人

 不允許程序員透露薪資!!!憑啥?

 程序員帶娃有多“恐怖” ?!

 有個大神級女朋友是什麼體驗


在看點這裏好文分享給更多人↓↓

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章