Kotlin中.equals()与==是否等价?重写为何出现重载冲突?
在Kotlin中尝试同时重写equals()函数,以及通过override operator fun equals重写==运算符时,会出现重载冲突错误。这是不是意味着==和.equals()是同一回事?如果不是,为什么不能同时重写?
代码示例
override fun equals(other: Any?): Boolean { if(other !is Injury){ return false } return bodyRegion == other.bodyRegion && injuryNature == other.injuryNature && injuryName == other.injuryName } override operator fun equals(other: Any?): Boolean{ if(other !is Injury){ return false } return bodyRegion == other.bodyRegion && injuryNature == other.injuryNature && injuryName == other.injuryName }
错误信息
重载冲突:public open fun equals(other: Any?): Boolean defined in com.redacted.redacted.Injury,public open fun equals(other: Any?): Boolean defined in com.redacted.redacted.Injury
问题解答
==和.equals()的关系
Kotlin里的==运算符本质就是调用对象的equals()方法,只不过做了空指针安全处理:当比较a == b时,实际执行逻辑是if (a === null) b === null else a.equals(b)。二者是同一逻辑的不同调用方式。为什么会出现重载冲突
Kotlin的operator关键字仅标记函数可被运算符(比如==)调用,不会改变函数签名。你写的两个equals方法参数、返回值完全一致,仅operator修饰符有区别,但在JVM层面二者是完全相同的方法,编译器会判定为重复定义,因此报重载冲突。正确的做法
只需要重写一次equals方法即可,加上operator关键字就能同时覆盖.equals()调用和==运算符的行为。示例代码如下:
override operator fun equals(other: Any?): Boolean { if(other !is Injury){ return false } return bodyRegion == other.bodyRegion && injuryNature == other.injuryNature && injuryName == other.injuryName }
即使不加operator,==依然能正常调用该方法(Kotlin会自动关联),但加上operator更符合运算符重载的语义规范。
内容的提问来源于stack exchange,提问作者Aashishkebab

