我正在学习Kotlin,具有C ++和Java背景。我希望以下内容可以打印true
,而不是false
。我知道==
映射到equals
。 equals
的默认实施不会比较每个成员,即firstName
和lastName
吗?如果是这样,它是否会将字符串值视为相等(因为==
再次映射到equal
)?显然,有一些与平等和身份有关的事情,我还没有在Kotlin做对。
class MyPerson(val firstName: String, val lastName: String)
fun main(args: Array<String>) {
println(MyPerson("Charlie", "Parker") == MyPerson("Charlie", "Parker"))
}
答案 0 :(得分:21)
<强>爪哇强>
在Java中,equals
的默认实现会比较变量的reference,这是==
总是的变量:
类
equals
的{{1}}方法实现了最具辨识力的方法 对象可能的等价关系;也就是说,对于任何非null 引用值x和y,当且仅当x 时,此方法返回Object
和y引用同一个对象(true
的值为x == y
)。
我们称之为“参考平等”。
<强>科特林强>
在Kotlin中true
编译为==
,而equals
相当于Java的===
。
每当我们想要结构而不是引用相等时,我们可以覆盖==
,默认情况下从不完成<正如您所建议的那样,正常类。在Kotlin中,我们可以使用equals
,编译器会根据构造函数属性自动创建一个实现(读取here)。
如果您覆盖data class
(反之亦然)手动,请务必覆盖hashCode
,并坚持使用两种方法中非常严格的contracts。 Kotlin的编译器生成的实现确实满足了合同。
答案 1 :(得分:6)
您描述的默认equals
实现仅适用于数据类。不适用于从Object
继承实现的常规类,只需使对象等于自身。
答案 2 :(得分:2)
== for equality
在Java中,您可以使用==来比较基元和引用类型。如果应用于基本类型,则Java ==比较值,而引用类型上的==比较引用。因此,在Java中,有着众所周知的总是称为equals的做法,并且存在众所周知的忘记这样做的问题。
在Kotlin中,==是比较两个对象的默认方式:它通过在引擎盖下调用equals来比较它们的值。因此,如果在类中重写了equals,则可以使用==安全地比较其实例。为了参考比较,您可以使用===运算符,它与Java中的==完全相同。
class MyPerson(val firstName: String, val lastName: String){
override fun equals(other: Any?): Boolean {
if (other == null || other !is MyPerson) return false
return firstName == other.firstName && lastName == other.lastName
}
}
fun main(args: Array<String>) {
println(MyPerson("Charlie", "Parker") == MyPerson("Charlie", "Parker")) // print "true"
}
在您的情况下,MyPerson
用于data class
自动生成通用方法的实现(toString
,equals
和hashCode
)。