@EqualsAndHashCode
Equality made easy:從對象的字段生成hashCode和equals實現。
Overview
任何類定義都可以用注釋@EqualsAndHashCode來讓 lombok 生成equals(Object other)和hashCode()方法的實現。默認情況下,它將使用所有非靜態、非瞬態字段,但您可以通過使用@EqualsAndHashCode.Include或標記類型成員來修改使用哪些字段(甚至指定要使用各種方法的輸出) @EqualsAndHashCode.Exclude。或者,您可以通過標記@EqualsAndHashCode.Include和使用來准確指定您希望使用的字段或方法@EqualsAndHashCode(onlyExplicitlyIncluded = true)。
如果應用於@EqualsAndHashCode擴展另一個類的類,則此功能會變得有些棘手。通常,為此類類自動生成equalsandhashCode方法是一個壞主意,因為超類還定義了字段,這些字段也需要 equals/hashCode 代碼,但不會生成此代碼。通過設置callSuper為true,您可以在生成的方法中包含超類的equals和hashCode方法。對於hashCode,結果super.hashCode()包含在哈希算法中,對於equals,如果超級實現認為它不等於傳入的對象,則生成的方法將返回false。請注意,並非所有equals實現都能正確處理這種情況。但是,lombok 生成的equals實現一定要正確處理這種情況,所以如果它也有一個 lombok 生成的equals方法,你可以安全地調用你的超類 equals。如果你有一個明確的超類,你不得不提供一些價值callSuper來承認你已經考慮過它;不這樣做會導致警告。
當你不擴展任何東西(你擴展)時 設置callSuper為truejava.lang.Object是一個編譯時錯誤,因為它會將生成的equals()和hashCode()實現變成具有與簡單地從繼承這些方法相同的行為java.lang.Object:只有同一個對象將等於每個其他並且將具有相同的hashCode。擴展另一個類時不設置callSuper為true會生成警告,因為除非超類沒有(平等重要)字段,否則 lombok 無法為您生成考慮到超類聲明的字段的實現。您需要編寫自己的實現,或依賴callSuper鏈接工具。您也可以使用lombok.equalsAndHashCode.callSuper配置鍵。
Lombok 0.10 中的新功能:除非您的類 isfinal和 extends java.lang.Object,否則 lombok 會生成一個canEqual方法,這意味着 JPA 代理仍然可以等於它們的基類,但是添加新狀態的子類不會破壞 equals 契約。本文解釋了為什么需要這種方法的復雜原因:How to Write an Equality Method in Java。如果層次結構中的所有類都是 scala 案例類和具有 lombok 生成的 equals 方法的類的混合,則所有相等性都將“正常工作”。如果您需要編寫自己的 equals 方法,則應始終canEqual在更改equalsand時覆蓋hashCode。
Lombok 1.14.0 中的新功能:要將注釋放在(以及,如果相關, )方法的other參數上,您可以使用. 不過要小心!這是一個實驗性功能。有關更多詳細信息,請參閱有關onX功能的文檔。 equalscanEqualonParam=@__({@AnnotationsHere})
Lombok 1.18.16 中的新功能:生成的結果hashCode()可以通過設置cacheStrategy為CacheStrategy.NEVER. 如果可以以任何會導致更改結果的方式修改帶注釋的類的對象,請不要hashCode()使用它。
with lombok
import lombok.EqualsAndHashCode; |
Vanilla Java
import java.util.Arrays; |
Supported configuration keys:
-
lombok.equalsAndHashCode.doNotUseGetters= [true|false](默認值:假) -
如果設置為,lombok 將直接訪問字段,而不是在生成和方法
true時使用 getter(如果可用) 。注釋參數“ ”,如果明確指定,則優先於此設置。equalshashCodedoNotUseGetters -
lombok.equalsAndHashCode.callSuper= [call|skip|warn](默認:警告) -
如果設置為
call,lombok 將生成對超類實現的調用,hashCode並且equals如果您的類擴展了某些東西。如果設置為skip不生成此類調用。默認行為類似於skip,帶有附加警告。 -
lombok.equalsAndHashCode.flagUsage= [warning|error](默認:未設置) -
如果配置,Lombok 會將任何使用標記
@EqualsAndHashCode為警告或錯誤。
Small print
數組是“深度”比較/hashCoded,這意味着包含自己的數組將導致StackOverflowErrors。但是,這種行為與 eg 沒有什么不同ArrayList。
您可以放心地假設所使用的 hashCode 實現不會在不同版本的 lombok 之間發生變化,但是這種保證並不是一成不變的;如果使用替代散列算法可以獲得顯着的性能改進,則將在未來的版本中替換。
出於相等的目的,NaN浮點數和雙精度數的 2 個(不是數字)值被認為是相等的,即使 'NaN == NaN' 會返回 false。這類似於java.lang.Double's equals 方法,實際上需要確保將對象與其自身的精確副本進行比較以返回true相等性。
如果有任何名為hashCodeorequals的方法,無論返回類型如何,都不會生成任何方法,而是發出警告。這兩種方法需要彼此同步,除非它生成所有方法,否則 lombok 無法保證,因此如果其中一種或兩種方法已經存在,您總是會收到警告。您可以標記任何方法以@lombok.experimental.Tolerate從 lombok 隱藏它們。
嘗試排除不存在或無論如何都會被排除的字段(因為它們是靜態的或瞬態的)會導致命名字段出現警告。
如果一個方法被標記為包含並且它與一個字段具有相同的名稱,它會替換該字段(該方法被包含,該字段被排除)。
在 lombok 1.16.22 之前,可以使用注釋的of和exclude參數完成包含/排除。@EqualsAndHashCode這種舊式包含機制仍然受支持,但將來會被棄用。
默認情況下,任何以 $ 符號開頭的變量都會被自動排除。您只能通過用 標記它們來包含它們@EqualsAndHashCode.Include。
如果要包含的字段存在 getter,則調用它而不是使用直接字段引用。可以抑制此行為:
@EqualsAndHashCode(doNotUseGetters = true)
如果您通過lombok.configkey配置了 nullity 注釋風格lombok.addNullAnnotations,則生成的equals方法以及任何canEqual方法的參數都將使用可為 null 的注釋進行注釋。如果您將@NonNullByDefault樣式注釋與嚴格的空值檢查結合使用,則這是必需的。
https://projectlombok.org/features/EqualsAndHashCode
