Kotlin 中 == 和 === 的区别

一、基本区别

在 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 代码非常重要。

更多分享

  1. 一文吃透Kotlin中冷流(Clod Flow)和热流(Hot Flow)
  2. 一文带你吃透Kotlin协程的launch()和async()的区别
  3. Kotlin 委托与扩展函数------新手入门
  4. Kotlin 作用域函数(let、run、with、apply、also)的使用指南
  5. 一文带你吃透Kotlin中 lateinit 和 by lazy 的区别和用法
  6. Kotlin 扩展方法(Extension Functions)使用详解
相关推荐
诸神黄昏EX5 小时前
Android Build系列专题【篇四:编译相关语法】
android
雨白7 小时前
优雅地处理协程:取消机制深度剖析
android·kotlin
leon_zeng07 小时前
更改 Android 应用 ID (ApplicationId) 后遭遇记
android·发布
2501_916007479 小时前
iOS 混淆工具链实战,多工具组合完成 IPA 混淆与加固(iOS混淆|IPA加固|无源码混淆|App 防反编译)
android·ios·小程序·https·uni-app·iphone·webview
Jeled10 小时前
Retrofit 与 OkHttp 全面解析与实战使用(含封装示例)
android·okhttp·android studio·retrofit
ii_best13 小时前
IOS/ 安卓开发工具按键精灵Sys.GetAppList 函数使用指南:轻松获取设备已安装 APP 列表
android·开发语言·ios·编辑器
2501_9159090613 小时前
iOS 26 文件管理实战,多工具组合下的 App 数据访问与系统日志调试方案
android·ios·小程序·https·uni-app·iphone·webview
limingade14 小时前
手机转SIP-手机做中继网关-落地线路对接软交换呼叫中心
android·智能手机·手机转sip·手机做sip中继网关·sip中继
RainbowC015 小时前
GapBuffer高效标记管理算法
android·算法
程序员码歌15 小时前
豆包Seedream4.0深度体验:p图美化与文生图创作
android·前端·后端