Hello, my question related to Kotlin bytecode generation for dataclasses with comparable properties inside. This question targets the following quote from java.lang.Comaparable
javadoc:
It is strongly recommended, but not strictly required that
(x.compareTo(y)==0)
==(x.equals(y))
. Generally speaking, any class that implements the Comparable interface and violates this condition should clearly indicate this fact. The recommended language is “Note: this class has a natural ordering that is inconsistent with equals.”
Interesting fact for me here, is that official JavaDoc states that this convention is something that is highly recommended to follow, but if not (not expected behaviour) the respectful developer should warn users of API about this inconvenience.
Example
Let’s assume that we have class like:
data class Character(val name: String, var salary: BigDecimal)
Then generated code for equals()
method will looks like:
public boolean equals(Object var1) {
if(this != var1) {
if(var1 instanceof Character) {
Character var2 = (Character)var1;
if(Intrinsics.areEqual(this.name, var2.name) && Intrinsics.areEqual(this.salary, var2.salary)) {
return true;
}
}
return false;
} else {
return true;
}
}
In fact, from a practical perspective, for Comparable
fields we usually have to invoke compareTo(....) == 0
:
this.salary.compareTo(var2.salary) == 0
One of the most widespread example is fields of BigDecimal
class where javadoc for equals()
method states that:
Unlike compareTo, this method considers two BigDecimal objects equal only if they are equal in value and scale (thus 2.0 is not equal to 2.00 when compared by this method).
Of course, we can change this behaviour, by manually overriding equals()
method like this:
override fun equals(other: Any?): Boolean {
if (this === other) return true
if (other?.javaClass != javaClass) return false
other as Character
if (name != other.name) return false
if (salary.compareTo(other.salary) != 0) return false
return true
}
But in case of data classes
IDEA won’t help us with code generation for overridden equals()/hashCode()
method (generation will be suggested only for toString()
method. Very sad
Proof:
Can someone from Kotlin core developers clarify the official position about equals()
code generation?
P.S. When it comes to Java/Kotlin, for me it feels like missing option in method generation
dialogue here:
Thank you in advance!