新來的同事不會用 Lombok,因此會引起本文!java
最近公司新來一個高 Java 的同事,搞了半天項目尚未跑起來,後來叫我過去幫他看一下,而後指着紅色的編譯錯誤和我說是否是代碼有問題。。ide
我頓時就心想,這人是否是太水了啊,工做三年了,簡單的編譯問題都搞不定?可是當我認真看了錯誤以後,發現……他居然沒裝 Lombok 插件……工具
而後我和他說出了問題所在,讓他安裝下 Lombok 插件再從新編譯下,他竟然和我說不知道什麼插件,感受他沒用過吧,甚至都沒有據說過。學習
好吧,我認了,我默默親自爲他把 Lombok 裝上了!ui
若是你沒用過,我也不以爲奇怪,Lombok 畢竟是團隊工具,但若是你也沒聽過,那就感受獲取新知識自我提高學習的能力有點弱了。this
固然,本篇不是教你怎麼用 Lombok,由於我以前就已經寫過教程分享過了,不會的能夠點擊這個連接看下,還熱乎着呢。spa
由於,最近也有看到一些公衆號在發放棄 Lombok 的文章,再結合最近一個新同事的狀況,也談談到底要不要用 Lombok。插件
一味地讓你們放棄,我感受有點偏激了,任何事物,存在就即合理,關鍵是利弊權衡的問題罷了。設計
用不用 Lombok,又是分兩派,公說公有理,婆說婆有理,仁者見仁,智者見智,誰也說服不了誰,相似 Eclipse 和 IntelliJ IDEA 誰更好用之爭!3d
我想說,爭這些沒任何意義,這徹底取決於團隊的決策,取決於你的團隊能不能 Hold 住這個東西,若是利 > 弊,用它就對了,若是弊 > 利,那就考慮放棄吧。
若是你是我的項目,請大膽用吧!
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 的註解,不然會顯示編譯報錯。
IntelliJ IDEA 插件示例:
若是某一我的爲了方便本身而使用,其餘人不肯意使用或者被迫使用,將致使團隊其餘成員代碼無法正常編譯,這也是問題的關鍵所在。
還有就是文章以前說的,來了一個新同事,若是他沒有相應的使用經驗,就須要額外的指導,對於老員工來講無疑也是一個額外的工做量。
@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 註解修飾的變量。
若是參數不少,都在一個構造器裏面,1、極不優雅,可讀性不好,2、不良設計。
與這個註解相關的還有 AllArgsConstructor 註解,包括全部參數,仍是當心爲妙。但在參數很少的時候仍是能夠代替使用的,但對不熟悉的人來講就是個潛在的問題。
2)@EqualsAndHashCode
Generates implementations for the {@code equals} and {@code hashCode} methods inherited by all objects, based on relevant fields.
這個註解用來生成 equals 和 hashCode 方法,裏面有一個 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;
是否調用父類的 equals 和 hashCode 方法,默認爲:false 不調用,這也是引發問題的關鍵。
來看下面的例子:
@Data
public class BaseStudent {
private int id;
}
@Data
@AllArgsConstructor
public class Student extends BaseStudent {
private String name;
private int age;
private String address;
}
把生成的 equals 和 hashCode 方法反編譯出來看下:
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 的問題,歡迎留言分享~