1. 概述

在 Kotlin 中,我们经常需要比较两个对象是否相等。Kotlin 提供了两个不同的运算符:=====,分别代表结构相等(Structural Equality)和引用相等(Referential Equality)。

这两个概念在 Java 中也有对应的体现:== 用于比较基本类型值或对象引用,而 equals() 方法用于结构比较。但在 Kotlin 中语法更加清晰,也更不容易出错。

2. 引用相等(===)

使用 === 运算符时,Kotlin 会比较两个对象的引用地址,即它们是否指向堆内存中的同一个对象。

这相当于 Java 中的 == 比较对象引用的行为。

示例:

val a = Integer(10)
val b = Integer(10)

println(a === b) // false

虽然 ab 的值都是 10,但它们是两个不同的 Integer 实例,因此引用不同,=== 返回 false

✅ 踩坑提醒:不要误以为 === 是比较值,它只比较引用。

3. 结构相等(==)

使用 == 运算符时,Kotlin 会调用对象的 equals() 方法进行比较,即比较两个对象的内容是否一致。

这相当于 Java 中的 equals() 方法。

示例:

val a = Integer(10)
val b = Integer(10)

println(a == b) // true

此时 == 会调用 Integer.equals(),判断值是否相同,所以返回 true

✅ 提示:如果你自定义了类,想要 == 正常工作,记得重写 equals()hashCode() 方法。

4. 复杂对象的比较

对于自定义的复杂对象,===== 的行为也是一致的:

  • === 比较引用
  • == 比较内容(通过 equals()

示例:

data class User(val name: String, val age: Int, val hobbies: List<String>)

val user1 = User("Alice", 25, listOf("Reading", "Hiking"))
val user2 = User("Alice", 25, listOf("Reading", "Hiking"))

println(user1 == user2)    // true
println(user1 === user2)   // false
  • == 返回 true 是因为 data class 自动生成了 equals() 方法,能递归比较内部字段,包括 List<String>
  • === 返回 false 是因为 user1user2 是两个不同的对象实例。

⚠️ 注意:如果是普通类(非 data class),必须手动实现 equals() 才能让 == 正常工作。

5. 数组的结构相等

在 Kotlin 中,数组的结构比较不能直接使用 ==,因为数组类型没有重写 equals() 方法。Kotlin 提供了两个扩展函数用于数组比较:

  • contentEquals():用于一维数组比较
  • contentDeepEquals():用于多维数组比较

示例:

val arr1 = arrayOf("Hiking", "Chess")
val arr2 = arrayOf("Hiking", "Chess")

println(arr1 contentEquals arr2) // true

如果使用 ==,结果会是 false,因为 arr1arr2 是两个不同的数组对象。

✅ 建议:在比较数组内容时,务必使用 contentEqualscontentDeepEquals

6. 总结

运算符 含义 对应 Java 行为 说明
== 结构相等 equals() 比较对象内容
=== 引用相等 ==(对象) 比较对象引用
  • 对基本类型(如 IntString)来说,===== 效果一样(因为自动装箱缓存)。
  • 对对象来说,要根据需求选择:需要比较内容时用 ==,需要判断是否为同一对象时用 ===
  • 对数组比较,使用 contentEquals 系列函数。

🔗 源码示例可在 GitHub 上找到。


原始标题:Difference Between “==” and “===” Operators in Kotlin