Kotlin密封类和哈希码/等式
我看到写的测试,我无法主张两个具有相同“子类”的密封类,并且引擎盖下的值相同。他们是独特的。
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()
}
}
}
此主要功能返回:
false
true
我真的没有得到为什么这种行为。我想这与密封类的性质有关,而我没有得到它?
提前致谢
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
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
Kotlin密封类不会覆盖默认的
equals()
从对象
Java类实现。这意味着使用其引用比较对象,因此a1
和a2
不相等。Kotlin数据类依次覆盖
equals()
方法,基于主构造函数中声明的所有属性(在 https://kotlinlang.org/docs/data-classes.html )。Kotlin Sealed classes do not override the default
equals()
implementation from theObject
Java class. This means that the objects are compared using their reference, hencea1
anda2
are not equal.Kotlin Data classes in their turn do override the
equals()
method based on all properties declared in the primary constructor (read more about them at https://kotlinlang.org/docs/data-classes.html).这是任何类别的正常行为 - 默认情况下,两个不同的实例都不相等,因为它检查了参考平等(即两个引用指向内存中的同一对象)。
数据类
提供默认等于
和hashcode
实现,忽略了参考等效性,只需比较对象类型,以及属性的值构造函数A
密封类
实际上只是类可以属于的特殊类型,该类型主要用于定义具有该类型的所有可能对象。它允许您将不同的类和对象分组在一起,并执行详尽的模式匹配(例如, 子句在mySealed
对象上操作时该类型的可能成员)您的
a
类是正常类,因此默认情况下两个实例不等。如果将其作为对象
在mySealed
中,则只有一个实例。从这个意义上讲,它可以像enum class
一样操作。一个密封的类让您可以混合和匹配这些不同类型的类型,并具有一些好处和缺点,您只需在密封类中制作
a
一个数据类,如果您希望它们具有相同的value ,但也是
mySealed
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