@EqualsAndHashCode
@EqualsAndHashCode
Equality made easy:从对象的字段生成hashCode
和equals
实现。
Overview
任何类定义都可以用注释@EqualsAndHashCode
来让 lombok 生成equals(Object other)
和hashCode()
方法的实现。默认情况下,它将使用所有非静态、非瞬态字段,但您可以通过使用@EqualsAndHashCode.Include
或标记类型成员来修改使用哪些字段(甚至指定要使用各种方法的输出) @EqualsAndHashCode.Exclude
。或者,您可以通过标记@EqualsAndHashCode.Include
和使用来准确指定您希望使用的字段或方法@EqualsAndHashCode(onlyExplicitlyIncluded = true)
。
如果应用于@EqualsAndHashCode
扩展另一个类的类,则此功能会变得有些棘手。通常,为此类类自动生成equals
andhashCode
方法是一个坏主意,因为超类还定义了字段,这些字段也需要 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
在更改equals
and时覆盖hashCode
。
Lombok 1.14.0 中的新功能:要将注释放在(以及,如果相关, )方法的other
参数上,您可以使用. 不过要小心!这是一个实验性功能。有关更多详细信息,请参阅有关onX功能的文档。 equals
canEqual
onParam=@__({@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(如果可用) 。注释参数“ ”,如果明确指定,则优先于此设置。equals
hashCode
doNotUseGetters
-
lombok.equalsAndHashCode.callSuper
= [call
|skip
|warn
](默认:警告) -
如果设置为
call
,lombok 将生成对超类实现的调用,hashCode
并且equals
如果您的类扩展了某些东西。如果设置为skip
不生成此类调用。默认行为类似于skip
,带有附加警告。 -
lombok.equalsAndHashCode.flagUsage
= [warning
|error
](默认:未设置) -
如果配置,Lombok 会将任何使用标记
@EqualsAndHashCode
为警告或错误。
Small print
数组是“深度”比较/hashCoded,这意味着包含自己的数组将导致StackOverflowError
s。但是,这种行为与 eg 没有什么不同ArrayList
。
您可以放心地假设所使用的 hashCode 实现不会在不同版本的 lombok 之间发生变化,但是这种保证并不是一成不变的;如果使用替代散列算法可以获得显着的性能改进,则将在未来的版本中替换。
出于相等的目的,NaN
浮点数和双精度数的 2 个(不是数字)值被认为是相等的,即使 'NaN == NaN' 会返回 false。这类似于java.lang.Double
's equals 方法,实际上需要确保将对象与其自身的精确副本进行比较以返回true
相等性。
如果有任何名为hashCode
orequals
的方法,无论返回类型如何,都不会生成任何方法,而是发出警告。这两种方法需要彼此同步,除非它生成所有方法,否则 lombok 无法保证,因此如果其中一种或两种方法已经存在,您总是会收到警告。您可以标记任何方法以@lombok.experimental.Tolerate
从 lombok 隐藏它们。
尝试排除不存在或无论如何都会被排除的字段(因为它们是静态的或瞬态的)会导致命名字段出现警告。
如果一个方法被标记为包含并且它与一个字段具有相同的名称,它会替换该字段(该方法被包含,该字段被排除)。
在 lombok 1.16.22 之前,可以使用注释的of
和exclude
参数完成包含/排除。@EqualsAndHashCode
这种旧式包含机制仍然受支持,但将来会被弃用。
默认情况下,任何以 $ 符号开头的变量都会被自动排除。您只能通过用 标记它们来包含它们@EqualsAndHashCode.Include
。
如果要包含的字段存在 getter,则调用它而不是使用直接字段引用。可以抑制此行为:
@EqualsAndHashCode(doNotUseGetters = true)
如果您通过lombok.config
key配置了 nullity 注释风格lombok.addNullAnnotations
,则生成的equals
方法以及任何canEqual
方法的参数都将使用可为 null 的注释进行注释。如果您将@NonNullByDefault
样式注释与严格的空值检查结合使用,则这是必需的。
https://projectlombok.org/features/EqualsAndHashCode