Kotlin里的`==`和`===`到底有啥不一樣?
作者:Reathin
1假設(shè)你和你兄弟用同款手機(jī):用==比較:是不是同型號(hào)、同顏色、同配置?(內(nèi)容一樣就算對(duì))用===比較:是不是同一部手機(jī)?(必須是同一個(gè)物體)
舉個(gè)栗子先感受下
假設(shè)你和你兄弟用同款手機(jī):
- 用==比較:是不是同型號(hào)、同顏色、同配置?(內(nèi)容一樣就算對(duì))
- 用===比較:是不是同一部手機(jī)?(必須是同一個(gè)物體)
這倆符號(hào)具體咋用?
==(內(nèi)容相等)
- 就像查戶口:檢查對(duì)象里每個(gè)屬性值是否完全一致
- 底層原理:自動(dòng)調(diào)用equals()方法(自己寫的類要重寫這個(gè)方法才有意義)
// 字符串比較(內(nèi)容相同就認(rèn))
val a = "蘋果14"
val b = "蘋果" + 14
println(a == b) // true(內(nèi)容一樣)
// 自定義類比較(沒重寫equals時(shí))
class 手機(jī)(val 型號(hào): String)
val 手機(jī)A = 手機(jī)("Mate60")
val 手機(jī)B = 手機(jī)("Mate60")
println(手機(jī)A == 手機(jī)B) // false(默認(rèn)只比內(nèi)存地址)
===(物理相等)
- 就像查身份證:必須是同一個(gè)對(duì)象才返回true
- 特殊福利:數(shù)字類型(比Int、Char、Boolean 等)Kotlin 會(huì)進(jìn)行優(yōu)化會(huì)被緩存復(fù)用,相同的值可能會(huì)指向同一個(gè)對(duì)象
// 同值不同對(duì)象
val 張三 = 手機(jī)("P70")
val 李四 = 手機(jī)("P70")
println(張三 === 李四) // false
// 特殊數(shù)字緩存
val 錢1 = 100
val 錢2 = 100
println(錢1 === 錢2) // true(在緩存范圍內(nèi))
val 大錢1 = 100000
val 大錢2 = 100000
println(大錢1 === 大錢2) // false(超出緩存)
什么時(shí)候用哪個(gè)?
用==的場(chǎng)合:
- 比用戶輸入的內(nèi)容
- 檢查兩個(gè)訂單是否相同商品
- 驗(yàn)證密碼是否正確
- 數(shù)據(jù)類(data class)自動(dòng)支持內(nèi)容比較
用===的場(chǎng)合:
- 檢查是不是同一個(gè)用戶登錄
- 單例模式驗(yàn)證實(shí)例
- 發(fā)現(xiàn)內(nèi)存泄漏時(shí)追蹤對(duì)象
- 優(yōu)化性能(比如避免重復(fù)創(chuàng)建對(duì)象)
容易踩坑的地方
坑1:空對(duì)象比較
val 空訂單: 訂單? = null
val 另一個(gè)空訂單: 訂單? = null
println(空訂單 == 另一個(gè)空訂單) // true(都空)
println(空訂單 === 另一個(gè)空訂單) // true(都指向null)
坑2:字符串陷阱
val 名字1 = "張三"
val 名字2 = "張" + "三"
println(名字1 === 名字2) // true(編譯器優(yōu)化成同一個(gè))
val 動(dòng)態(tài)名字 = StringBuilder().append("張").append("三").toString()
println(名字1 === 動(dòng)態(tài)名字) // false(動(dòng)態(tài)生成的地址不同)
總結(jié)
雙等號(hào),比內(nèi)容; 三等號(hào),查身份。 基本類型看緩存, 對(duì)象比較要區(qū)分。
- 優(yōu)先用==比較內(nèi)容,除非確實(shí)需要判斷是否是同一個(gè)對(duì)象
- 寫數(shù)據(jù)類時(shí)直接用data class,自動(dòng)幫你實(shí)現(xiàn)equals()
- 遇到===返回true但內(nèi)容不同?檢查是否修改了可變對(duì)象
- 調(diào)試時(shí)用===快速定位對(duì)象是否被意外復(fù)用
操作符 | 名稱 | 比較內(nèi)容 | Java |
== | 結(jié)構(gòu)相等 | 對(duì)象內(nèi)容是否相同 | equals() |
=== | 引用相等 | 是否引用同一個(gè)對(duì)象 | == |
責(zé)任編輯:武曉燕
來源:
沐雨花飛碟