Kotlin密封类和哈希码/等式

发布于 2025-01-28 02:03:48 字数 999 浏览 6 评论 0原文

我看到写的测试,我无法主张两个具有相同“子类”的密封类,并且引擎盖下的值相同。他们是独特的。

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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

压抑⊿情绪 2025-02-04 02:03:48

Kotlin密封类不会覆盖默认的equals()对象 Java类实现。这意味着使用其引用比较对象,因此a1a2不相等。

Kotlin数据类依次覆盖equals()方法,基于主构造函数中声明的所有属性(在 https://kotlinlang.org/docs/data-classes.html )。

Kotlin Sealed classes do not override the default equals() implementation from the Object Java class. This means that the objects are compared using their reference, hence a1 and a2 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).

我喜欢麦丽素 2025-02-04 02:03:48

这是任何类别的正常行为 - 默认情况下,两个不同的实例都不相等,因为它检查了参考平等(即两个引用指向内存中的同一对象)。

class NormalClass(val value: String)

val a = NormalClass("foo")
val b = NormalClass("foo")
println(a == b)

> false

数据类提供默认等于hashcode实现,忽略了参考等效性,只需比较对象类型,以及属性的值构造函数

data class DataClass(val value: String)

val a = DataClass("foo")
val b = DataClass("foo")
println(a == b)

> true

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).

class NormalClass(val value: String)

val a = NormalClass("foo")
val b = NormalClass("foo")
println(a == b)

> false

data classes provide a default equals and hashCode implementation that ignores referential equality, and just compares the object type, and the values of the properties in the constructor

data class DataClass(val value: String)

val a = DataClass("foo")
val b = DataClass("foo")
println(a == b)

> true

A 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. a when clause operating on a MySealed 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 an object in MySealed, there would only be one instance of it. In that sense, it can operate a little like an enum class. A sealed class lets you mix and match these different types, with some benefits and drawbacks

You can just make A a data class inside the sealed class, if you want them to match if they have the same value, but also be a MySealed

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文