I'm seeing writing a test that I cannot assert two sealed classes with same "subclass" and same value under the hood are equal. They are distinct.
fun main() {
val a1 = MySealed.A("foo")
val a2 = MySealed.A("foo")
System.out.println(a1 == a2)
val a3 = MySealedWithEqualsAndHashCodeOverriden.A("foo")
val a4 = MySealedWithEqualsAndHashCodeOverriden.A("foo")
System.out.println(a3 == a4)
}
sealed class MySealed(val value: String) {
class A(value: String) : MySealed(value)
}
sealed class MySealedWithEqualsAndHashCodeOverriden(val value: String) {
class A(value: String) : MySealedWithEqualsAndHashCodeOverriden(value) {
override fun equals(other: Any?): Boolean {
if (this === other) return true
if (javaClass != other?.javaClass) return false
return true
}
override fun hashCode(): Int {
return javaClass.hashCode()
}
}
}
This main function returns:
false
true
I do not really get why that behaviour.. I guess it is related to the nature of sealed classes it self and I'm not getting it?
Thanks in advance
That's normal behaviour for any class - two different instances are not equal by default, because it checks for referential equality (i.e. the two references are pointing at the same object in memory).
data class
es provide a defaultequals
andhashCode
implementation that ignores referential equality, and just compares the object type, and the values of the properties in the constructorA
sealed class
is really just a special type that a class can belong to, which is mostly used for things like defining all the possible objects that have that type. It allows you to group disparate classes and objects together, and do things like exhaustive pattern matching (e.g. awhen
clause operating on aMySealed
object can tell when you've checked all the possible members of that type)Your
A
class is a normal class, so two instances of it are not equal by default. If you made it anobject
inMySealed
, there would only be one instance of it. In that sense, it can operate a little like anenum class
. A sealed class lets you mix and match these different types, with some benefits and drawbacksYou can just make
A
a data class inside the sealed class, if you want them to match if they have the samevalue
, but also be aMySealed