公司來了個新同事不會用 Lombok,還說我代碼有問題!

新來的同事不會用 Lombok,所以會引發本文!

背景

最近公司新來一個搞 Java 的同事,搞了半天項目還沒有跑起來,後來叫我過去幫他看一下,然後指着紅色的編譯錯誤和我說是不是代碼有問題。。

我頓時就心想,這人是不是太水了啊,工作三年了,簡單的編譯問題都搞不定?但是當我認真看了錯誤之後,發現……他竟然沒裝 Lombok 插件……

然後我和他說出了問題所在,讓他安裝下 Lombok 插件再重新編譯下,他居然和我說不知道什麼插件,感覺他沒用過吧,甚至都沒有聽說過。

好吧,我認了,我默默親自爲他把 Lombok 裝上了!

如果你沒用過,我也不覺得奇怪,Lombok 畢竟是團隊工具,但如果你也沒聽過,那就感覺獲取新知識自我提升學習的能力有點弱了,或者不怎麼看公衆號。

當然,本篇不是教你怎麼用 Lombok,因爲我之前就已經寫過教程分享過了,不會的可以點擊這個鏈接看下,還熱乎着呢。

放棄 Lombok?

因爲,最近,棧長也有看到一些公衆號在發放棄 Lombok 的文章,再結合最近一個新同事的情況,也談談到底要不要用 Lombok

一味地勁大家放棄,我感覺有點偏激了,任何事物,存在就即合理,關鍵是利弊權衡的問題罷了。

用不用 Lombok,又是分兩派,公說公有理,婆說婆有理,仁者見仁,智者見智,誰也說服不了誰,類似 EclipseIntelliJ IDEA 誰更好用之爭!

我想說,爭這些沒任何意義,這完全取決於團隊的決策,取決於你的團隊能不能 Hold 住這個東西,如果利 > 弊,用它就對了,如果弊 > 利,那就考慮放棄吧。

如果你是個人項目,請大膽用吧!

Lombok 的弊端

Lombok 的好處就不說了,就是幫我們大量簡化代碼,這裏重點說下爲什麼有人不推薦使用 Lombok

一、需要額外的組件

使用 Lombok 需要兩個必要的組件:

1)Lombok 依賴包

使用 Lombok 的註解,就必須引用它的依賴,最後編譯成最終的 class 類,如 Maven 依賴示例:

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

這個不會引起問題,因爲它是代碼的一部分,而且在項目一開始的時候就引入進去了。

2)Lombok IDE 插件

Eclipse/ IntelliJ IDEA 都提供了 Lombok 插件,用來識別 Lombok 的註解,否則會顯示編譯報錯。如果你對 IDEA 還不會使用可以關注Java技術棧公衆號在後臺回覆IDEA獲取系列教程。

IntelliJ IDEA 插件示例:

如果某一個人爲了方便自己而使用,其他人不願意使用或者被迫使用,將導致團隊其他成員代碼沒法正常編譯,這也是問題的關鍵所在。

還有就是文章之前說的,來了一個新同事,如果他沒有相應的使用經驗,就需要額外的指導,對於老員工來說無疑也是一個額外的工作量。

二、@Data 註解的坑

@Data 註解用在類上,等同於下面這幾個註解合集:

  • @Getter
  • @Setter
  • @RequiredArgsConstructor
  • @ToString
  • @EqualsAndHashCode

@Getter, @Setter, @ToString 很簡單,用起來也沒問題,而 @RequiredArgsConstructor@EqualsAndHashCode 需要注意下。

1)RequiredArgsConstructor

Generates a constructor with required arguments.Required arguments are final fields and fields with constraints such as {@code @NonNull}.

即生成一個類構造器,參數包含所有用 final 修飾、以及 @NonNull 註解修飾的變量。

如果參數很多,都在一個構造器裏面,一、極不優雅,可讀性很差,二、不良設計。

與這個註解相關的還有 AllArgsConstructor 註解,包括所有參數,還是小心爲妙。但在參數不多的時候還是可以代替使用的,但對不熟悉的人來說就是個潛在的問題。

2)@EqualsAndHashCode

Generates implementations for the {@code equals} and {@code hashCode} methods inherited by all objects, based on relevant fields.

這個註解用來生成 equalshashCode 方法,裏面有一個 callSuper() 方法:

/**
 * Call on the superclass's implementations of {@code equals} and {@code hashCode} before calculating for the fields in this class.
 * <strong>default: false</strong>
 * 
 * @return Whether to call the superclass's {@code equals} implementation as part of the generated equals algorithm.
 */
boolean callSuper() default false;

是否調用父類的 equalshashCode 方法,默認爲:false 不調用,這也是引起問題的關鍵。

來看下面的例子:

@Data
public class BaseStudent {

    private int id;

}

@Data
@AllArgsConstructor
public class Student extends BaseStudent {

    private String name;

    private int age;

    private String address;

}

把生成的 equalshashCode 方法反編譯出來看下:

public boolean equals(Object o) {
    if (o == this)
      return true; 
    if (!(o instanceof Student))
      return false; 
    Student other = (Student)o;
    if (!other.canEqual(this))
      return false; 
    Object this$name = getName(), other$name = other.getName();
    if ((this$name == null) ? (other$name != null) : !this$name.equals(other$name))
      return false; 
    if (getAge() != other.getAge())
      return false; 
    Object this$address = getAddress(), other$address = other.getAddress();
    return !((this$address == null) ? (other$address != null) : !this$address.equals(other$address));
}

public int hashCode() {
    int PRIME = 59;
    result = 1;
    Object $name = getName();
    result = result * 59 + (($name == null) ? 43 : $name.hashCode());
    result = result * 59 + getAge();
    Object $address = getAddress();
    return result * 59 + (($address == null) ? 43 : $address.hashCode());
}

最後判斷如果不是同一個對象時,會判斷每個變量的值,但是此時父類的值不參與比較,這顯然是不符合邏輯的,另外 hashCode 方法父類的值也沒有參與運算,也是潛在問題。

三、代碼跟蹤調試

使用 Lombok 可以幫助我們少寫很多代碼,但同時也降低了代碼可讀性和跟蹤、調試的問題。

比如,我想查找 getName() 方法都被哪些地方引用了,就不能直接按快捷鍵了,可能需要費一翻力氣。

代碼調試也有問題,比如我跟進 getAddress 方法,雖然進不去該方法,但可以直接跳到對應的變量,顯示對應的值。

但是我想調試生成後的 hashCode 方法的運算過程,代碼沒有,斷點都沒法打,怎麼調試?

即使如此,我覺得這個問題不大,我們很少去跟蹤這些代碼,我們也可以通過其他方式來曲線解決。

總結

以上一些問題都是使用 Lombok 不可避免的,這還只是已知的問題,未知的呢?

Lombok 雖好,你也要遵循團隊的規範,能用的情況下再用,也不能亂用,不瞭解其構造,亂用就容易出現問題的。

最好的方法是,作用域最小化,需要什麼就用什麼,註解單獨使用,而不是三七二十一什麼類上來都來一個 @Data 什麼的,出問題就欲哭無淚了。

所有種種潛在的問題都是領導者不願意看到的,所以,有的公司是明令禁止使用 Lombok 的,我個人是不站邊,適度運用就好,但不要過度依賴。

如果你還遇到其他使用 Lombok 的問題,歡迎留言分享~

關注公衆號Java技術棧回覆"面試"獲取我整理的2020最全面試題及答案。

推薦去我的博客閱讀更多:

1.Java JVM、集合、多線程、新特性系列教程

2.Spring MVC、Spring Boot、Spring Cloud 系列教程

3.Maven、Git、Eclipse、Intellij IDEA 系列工具教程

4.Java、後端、架構、阿里巴巴等大廠最新面試題

覺得不錯,別忘了點贊+轉發哦!

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