一、基本区别
在 Kotlin 中,==
和 ===
是两个不同的比较操作符:
==
:结构相等(Structural equality),比较两个对象的内容是否相同===
:引用相等(Referential equality),比较两个引用是否指向同一个对象
二、详细解释与示例
1. ==
操作符(结构相等)
==
操作符会调用对象的 equals()
方法来比较两个对象的内容是否相同。
kotlin
val a = "Hello"
val b = "Hello"
val c = "HELLO".toLowerCase()
println(a == b) // 输出: true
println(a == c) // 输出: true
对于自定义类,默认会使用从 Any
继承的 equals()
方法(类似于 Java 中的 ==
),但你可以重写它:
kotlin
class Person(val name: String, val age: Int) {
override fun equals(other: Any?): Boolean {
if (this === other) return true
if (other !is Person) return false
return name == other.name && age == other.age
}
override fun hashCode(): Int {
return name.hashCode() * 31 + age
}
}
val p1 = Person("Alice", 25)
val p2 = Person("Alice", 25)
val p3 = Person("Bob", 30)
println(p1 == p2) // 输出: true
println(p1 == p3) // 输出: falsen
class Person(val name: String, val age: Int) {
override fun equals(other: Any?): Boolean {
if (this === other) return true
if (other !is Person) return false
return name == other.name && age == other.age
}
override fun hashCode(): Int {
return name.hashCode() * 31 + age
}
}
val p1 = Person("Alice", 25)
val p2 = Person("Alice", 25)
val p3 = Person("Bob", 30)
println(p1 == p2) // 输出: true
println(p1 == p3) // 输出: false
2. ===
操作符(引用相等)
===
操作符检查两个引用是否指向内存中的同一个对象:
kotlin
val list1 = listOf(1, 2, 3)
val list2 = listOf(1, 2, 3)
val list3 = list1
println(list1 === list2) // 输出: false (内容相同但不是同一个对象)
println(list1 === list3) // 输出: true (引用同一个对象)
对于基本类型(如 Int、Char、Boolean 等),Kotlin 会进行优化,相同的值可能会指向同一个对象:
kotlin
val a: Int = 1000
val b: Int = 1000
println(a === b) // 输出: true (由于整数缓存)
val c: Int = 10000
val d: Int = 10000
println(c === d) // 输出: false (超出缓存范围)
三、使用场景
1. 使用 ==
的场景:
- 比较两个对象的内容是否相同
- 检查字符串内容是否相等
- 比较集合内容是否相同
- 自定义类的相等性比较
2. 使用 ===
的场景:
- 检查两个变量是否引用同一个对象
- 实现单例模式时检查实例
- 优化性能时避免创建重复对象
- 调试时检查对象引用
三、空安全考虑
Kotlin 的空安全特性也适用于这些操作符:
kotlin
val s1: String? = null
val s2: String? = null
println(s1 == s2) // 输出: true
println(s1 === s2) // 输出: true
val s3 = "Kotlin"
val s4: String? = "Kotlin"
println(s3 == s4) // 输出: true (内容相同)
println(s3 === s4) // 输出: true (由于字符串驻留)
四、总结
操作符 | 名称 | 比较内容 | 相当于 Java 中的 |
---|---|---|---|
== |
结构相等 | 对象内容是否相同 | equals() |
=== |
引用相等 | 是否引用同一个对象 | == |
理解这两个操作符的区别对于编写正确且高效的 Kotlin 代码非常重要。