1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
|
<#import "_features.html" as f>
<@f.scaffold title="@EqualsAndHashCode" logline="Equality made easy: Generates <code>hashCode</code> and <code>equals</code> implementations from the fields of your object.">
<@f.overview>
<p>
Any class definition may be annotated with <code>@EqualsAndHashCode</code> to let lombok generate implementations of the <code>equals(Object other)</code> and <code>hashCode()</code> methods. By default, it'll use all non-static, non-transient fields, but you can modify which fields are used (and even specify that the output of various methods is to be used) by marking type members with <code>@EqualsAndHashCode.Include</code> or <code>@EqualsAndHashCode.Exclude</code>. Alternatively, you can specify exactly which fields or methods you wish to be used by marking them with <code>@EqualsAndHashCode.Include</code> and using <code>@EqualsAndHashCode(onlyExplicitlyIncluded = true)</code>.
</p><p>
If applying <code>@EqualsAndHashCode</code> to a class that extends another, this feature gets a bit trickier. Normally, auto-generating an <code>equals</code> and <code>hashCode</code> method for such classes is a bad idea, as the superclass also defines fields, which also need equals/hashCode code but this code will not be generated. By setting <code>callSuper</code> to <em>true</em>, you can include the <code>equals</code> and <code>hashCode</code> methods of your superclass in the generated methods. For <code>hashCode</code>, the result of <code>super.hashCode()</code> is included in the hash algorithm, and for<code>equals</code>, the generated method will return false if the super implementation thinks it is not equal to the passed in object. Be aware that not all <code>equals</code> implementations handle this situation properly. However, lombok-generated <code>equals</code> implementations <strong>do</strong> handle this situation properly, so you can safely call your superclass equals if it, too, has a lombok-generated <code>equals</code> method. If you have an explicit superclass you are forced to supply some value for <code>callSuper</code> to acknowledge that you've considered it; failure to do so results in a warning.
</p><p>
Setting <code>callSuper</code> to <em>true</em> when you don't extend anything (you extend <code>java.lang.Object</code>) is a compile-time error, because it would turn the generated <code>equals()</code> and <code>hashCode()</code> implementations into having the same behaviour as simply inheriting these methods from <code>java.lang.Object</code>: only the same object will be equal to each other and will have the same hashCode. Not setting <code>callSuper</code> to <em>true</em> when you extend another class generates a warning, because unless the superclass has no (equality-important) fields, lombok cannot generate an implementation for you that takes into account the fields declared by your superclasses. You'll need to write your own implementations, or rely on the <code>callSuper</code> chaining facility. You can also use the <code>lombok.equalsAndHashCode.callSuper</code> config key.
</p><p>
<em>NEW in Lombok 0.10: </em>Unless your class is <code>final</code> and extends <code>java.lang.Object</code>, lombok generates a <code>canEqual</code> method which means JPA proxies can still be equal to their base class, but subclasses that add new state don't break the equals contract. The complicated reasons for why such a method is necessary are explained in this paper: <a href="https://www.artima.com/lejava/articles/equality.html">How to Write an Equality Method in Java</a>. If all classes in a hierarchy are a mix of scala case classes and classes with lombok-generated equals methods, all equality will 'just work'. If you need to write your own equals methods, you should always override <code>canEqual</code> if you change <code>equals</code> and <code>hashCode</code>.
</p><p>
<em>NEW in Lombok 1.14.0: </em>To put annotations on the <code>other</code> parameter of the <code>equals</code> (and, if relevant, <code>canEqual</code>) method, you can use <code>onParam=@__({@AnnotationsHere})</code>. Be careful though! This is an experimental feature. For more details see the documentation on the <a ng-click="toFeature('on-x')">onX</a> feature.
</p><p>
<em>NEW in Lombok 1.18.16: </em>Caching the result of the generated <code>hashCode()</code> can be cached by setting <code>cacheStrategy</code> to a value other than <code>CacheStrategy.NEVER</code>. <em>Do not</em> use this if objects of the annotated class can be modified in any way that would lead to the result of <code>hashCode()</code> changing.
</p>
</@f.overview>
<@f.snippets name="EqualsAndHashCode" />
<@f.confKeys>
<dt>
<code>lombok.equalsAndHashCode.doNotUseGetters</code> = [<code>true</code> | <code>false</code>] (default: false)
</dt><dd>
If set to <code>true</code>, lombok will access fields directly instead of using getters (if available) when generating <code>equals</code> and <code>hashCode</code> methods. The annotation parameter '<code>doNotUseGetters</code>', if explicitly specified, takes precedence over this setting.
</dd><dt>
<code>lombok.equalsAndHashCode.callSuper</code> = [<code>call</code> | <code>skip</code> | <code>warn</code>] (default: warn)
</dt><dd>
If set to <code>call</code>, lombok will generate calls to the superclass implementation of <code>hashCode</code> and <code>equals</code> if your class extends something. If set to <code>skip</code> no such calls are generated. The default behaviour is like <code>skip</code>, with an additional warning.
</dd><dt>
<code>lombok.equalsAndHashCode.flagUsage</code> = [<code>warning</code> | <code>error</code>] (default: not set)
</dt><dd>
Lombok will flag any usage of <code>@EqualsAndHashCode</code> as a warning or error if configured.
</dd>
</@f.confKeys>
<@f.smallPrint>
<p>
Arrays are 'deep' compared/hashCoded, which means that arrays that contain themselves will result in <code>StackOverflowError</code>s. However, this behaviour is no different from e.g. <code>ArrayList</code>.
</p><p>
You may safely presume that the hashCode implementation used will not change between versions of lombok, however this guarantee is not set in stone; if there's a significant performance improvement to be gained from using an alternate hash algorithm, that will be substituted in a future version.
</p><p>
For the purposes of equality, 2 <code>NaN</code> (not a number) values for floats and doubles are considered equal, eventhough 'NaN == NaN' would return false. This is analogous to <code>java.lang.Double</code>'s equals method, and is in fact required to ensure that comparing an object to an exact copy of itself returns <code>true</code> for equality.
</p><p>
If there is <em>any</em> method named either <code>hashCode</code> or <code>equals</code>, regardless of return type, no methods will be generated, and a warning is emitted instead. These 2 methods need to be in sync with each other, which lombok cannot guarantee unless it generates all the methods, hence you always get a warning if one <em>or</em> both of the methods already exist. You can mark any method with <code>@lombok.experimental.Tolerate</code> to hide them from lombok.
</p><p>
Attempting to exclude fields that don't exist or would have been excluded anyway (because they are static or transient) results in warnings on the named fields.
</p><p>
If a method is marked for inclusion and it has the same name as a field, it replaces the field (the method is included, the field is excluded).
</p><p>
Prior to lombok 1.16.22, inclusion/exclusion could be done with the <code>of</code> and <code>exclude</code> parameters of the <code>@EqualsAndHashCode</code> annotation. This old-style inclusion mechanism is still supported but will be deprecated in the future.
</p><p>
By default, any variables that start with a $ symbol are excluded automatically. You can only include them by marking them with <code>@EqualsAndHashCode.Include</code>.
</p><p>
If a getter exists for a field to be included, it is called instead of using a direct field reference. This behaviour can be suppressed:<br />
<code>@EqualsAndHashCode(doNotUseGetters = true)</code>
</p><p>
If you have configured a nullity annotation flavour via <a href="configuration"><code>lombok.config</code></a> key <code>lombok.addNullAnnotations</code>, the parameter of both the generated <code>equals</code> method as well as any <code>canEqual</code> method is annotated with a nullable annotation. This is required if you use a <code>@NonNullByDefault</code> style annotation in combination with strict nullity checking.
</p>
</@f.smallPrint>
</@f.scaffold>
|