當(dāng)你在使用 Lombok 的 @Data 注解時(shí)更卒,其實(shí)會(huì)有一些坑需要關(guān)注蚯涮,今天就讓我們來(lái)見(jiàn)識(shí)一下拓颓。
Lombok
先來(lái)簡(jiǎn)單介紹一下 Lombok 溉躲,其官方介紹如下:
Project Lombok makes java a spicier language by adding 'handlers' that know how to build and compile simple, boilerplate-free, not-quite-java code.
大致意思是 Lombok 通過(guò)增加一些"處理程序"喉誊,可以讓 Java 代碼變得簡(jiǎn)潔渔隶、快速羔挡。
Lombok 提供了一系列的注解幫助我們簡(jiǎn)化代碼,比如:
注解名稱功能
@Setter自動(dòng)添加類中所有屬性相關(guān)的 set 方法
@Getter自動(dòng)添加類中所有屬性相關(guān)的 get 方法
@Builder使得該類可以通過(guò) builder (建造者模式)構(gòu)建對(duì)象
@RequiredArgsConstructor生成一個(gè)該類的構(gòu)造方法间唉,禁止無(wú)參構(gòu)造
@ToString重寫(xiě)該類的toString()方法
@EqualsAndHashCode重寫(xiě)該類的equals()和hashCode()方法
@Data等價(jià)于上面的@Setter绞灼、@Getter、@RequiredArgsConstructor呈野、@ToString低矮、@EqualsAndHashCode
看起來(lái)似乎這些注解都很正常,并且對(duì)我們的代碼也有一定的優(yōu)化被冒,那為什么說(shuō)@Data注解存在坑呢军掂?
@Data注解
內(nèi)部實(shí)現(xiàn)
由上面的表格我們可以知道,@Data是包含了@EqualsAndHashCode的功能昨悼,那么它究竟是如何重寫(xiě)equals()和hashCode()方法的呢蝗锥?
問(wèn)題總結(jié)
對(duì)于父類是Object且使用了@EqualsAndHashCode(callSuper = true)注解的類,這個(gè)類由 Lombok 生成的equals()方法只有在兩個(gè)對(duì)象是同一個(gè)對(duì)象時(shí)率触,才會(huì)返回 true 终议,否則總為 false ,無(wú)論它們的屬性是否相同葱蝗。
這個(gè)行為在大部分時(shí)間是不符合預(yù)期的穴张,equals()失去了其意義。即使我們期望equals()是這樣工作的两曼,那么其余的屬性比較代碼便是累贅皂甘,會(huì)大幅度降低代碼的分支覆蓋率。
解決方法
1悼凑、用了@Data就不要有繼承關(guān)系偿枕,類似 Kotlin 的做法。
2户辫、自己重寫(xiě)equals()益老, Lombok 不會(huì)對(duì)顯式重寫(xiě)的方法進(jìn)行生成。
3寸莫、顯式使用@EqualsAndHashCode(callSuper = true), Lombok 會(huì)以顯式指定的為準(zhǔn)档冬。
總結(jié)
以上便是我在使用@Data時(shí)碰到的問(wèn)題以及自己的一些思考膘茎,在現(xiàn)在的項(xiàng)目桃纯,我干脆不再使用該注解。如果你有什么想法披坏,歡迎在下方留言态坦。