Since Checkstyle 3.2
equals()
method
also override method equals(Object)
.
Covariant equals()
- method that is similar to equals(Object)
,
but with a covariant parameter type (any subtype of Object).
Notice: the enums are also checked, even
though they cannot override equals(Object)
. The reason is
to point out that implementing equals()
in enums is considered an
awful practice: it may cause having two different enum values that are equal using
covariant enum method, and not equal when compared normally.
Inspired by Finding Bugs is Easy, chapter '4.5 Bad Covariant Definition of Equals (Eq)':
Java classes and records may override the equals(Object)
method to define
a predicate for object equality. This method is used by many of the Java runtime
library classes; for example, to implement generic containers.
Programmers sometimes mistakenly use the type of their class Foo
as the type of the parameter to equals()
:
public boolean equals(Foo obj) {...}
This covariant version of equals()
does not override the version in the
Object
class, and it may lead to unexpected behavior at runtime,
especially if the class is used with one of the standard collection classes
which expect that the standard equals(Object)
method is overridden.
This kind of bug is not obvious because it looks correct, and in circumstances where the class is accessed through the references of the class type (rather than a supertype), it will work correctly. However, the first time it is used in a container, the behavior might be mysterious. For these reasons, this type of bug can elude testing and code inspections.
To configure the check:
<module name="Checker"> <module name="TreeWalker"> <module name="CovariantEquals"/> </module> </module>
For example:
public class Example1 { public boolean equals(Example1 same) { // violation return false; } record Test(String str) { public boolean equals(Test same) { // violation return false; } } }
The same class without violations:
public class Example2 { public boolean equals(Example2 same) { // no violation return false; } public boolean equals(Object o) { return false; } record Test(String str) { public boolean equals(Test same) { // no violation return false; } public boolean equals(Object o) { return false; } } }
All messages can be customized if the default message doesn't suit you. Please see the documentation to learn how to.
com.puppycrawl.tools.checkstyle.checks.coding