新來的同事不會用 Lombok
,所以會引發本文!
背景
最近公司新來一個搞 Java 的同事,搞了半天項目還沒有跑起來,后來叫我過去幫他看一下,然后指着紅色的編譯錯誤和我說是不是代碼有問題。。
我頓時就心想,這人是不是太水了啊,工作三年了,簡單的編譯問題都搞不定?但是當我認真看了錯誤之后,發現……他竟然沒裝 Lombok
插件……
然后我和他說出了問題所在,讓他安裝下 Lombok
插件再重新編譯下,他居然和我說不知道什么插件,感覺他沒用過吧,甚至都沒有聽說過。
好吧,我認了,我默默親自為他把 Lombok
裝上了!
如果你沒用過,我也不覺得奇怪,Lombok
畢竟是團隊工具,但如果你也沒聽過,那就感覺獲取新知識自我提升學習的能力有點弱了,或者不怎么看公眾號。
當然,本篇不是教你怎么用 Lombok
,因為我之前就已經寫過教程分享過了,不會的可以點擊這個鏈接看下,還熱乎着呢。
放棄 Lombok?
因為,最近,棧長也有看到一些公眾號在發放棄 Lombok
的文章,再結合最近一個新同事的情況,也談談到底要不要用 Lombok
。
一味地勁大家放棄,我感覺有點偏激了,任何事物,存在就即合理,關鍵是利弊權衡的問題罷了。
用不用 Lombok
,又是分兩派,公說公有理,婆說婆有理,仁者見仁,智者見智,誰也說服不了誰,類似 Eclipse
和 IntelliJ 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.
這個注解用來生成 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
的問題,歡迎留言分享~
關注公眾號Java技術棧回復"面試"獲取我整理的2020最全面試題及答案。
推薦去我的博客閱讀更多:
2.Spring MVC、Spring Boot、Spring Cloud 系列教程
3.Maven、Git、Eclipse、Intellij IDEA 系列工具教程
覺得不錯,別忘了點贊+轉發哦!