歡迎關(guān)注 二師兄Kotlin
轉(zhuǎn)載請(qǐng)注明出處 二師兄kotlin
kotlin "null"
Kotlin的類(lèi)型設(shè)計(jì)系統(tǒng)旨在消滅NullPinterException(下文簡(jiǎn)稱(chēng)NPE),從此媽媽再也不用擔(dān)心代碼里面的空指針了。
當(dāng)然,Kotlin只是在很大程度上幫你干掉NPE,如果你非得搞出來(lái),Kotlin也滿(mǎn)足你的欲望,以下幾種情況能幫你看到熟悉的NPE:
- 顯示調(diào)用
throw NullPointerException() - 使用
!!操作符 - 外部java代碼導(dǎo)致*
- 一些在構(gòu)造函數(shù)中未初始化的變量到處使用
在Kotlin里,系統(tǒng)可以區(qū)分引用是否可以null 引用,舉栗來(lái)說(shuō),一個(gè)String的常規(guī)變量不能持有null:
var a: String = "abc"
a = null // compilation error
為了允許它為null,我們需要聲明一個(gè)允許為null的string,寫(xiě)法為String?:
var b: String? = "abc"
b = null // ok
現(xiàn)在,如果你調(diào)用 a 的一個(gè)方法或者訪問(wèn)屬性, 可以打一千個(gè)保票不會(huì)引起 NPE:
val l = a.length
但是如果你訪問(wèn) b 的一些屬性, 編譯器會(huì)直接給你一個(gè)error:
val l = b.length // error: variable 'b' can be null
但是就算你給我報(bào)error,我還是想訪問(wèn)啊,腫么辦。。。
解決方法如下:
方法1 自己做檢查
首先,我們可以顯示的檢查 b 是否為空,手動(dòng)處理不同的情況:
val l: Int = if (b != null) b.length else -1
或者
if (b != null && b.length > 0)
print("String of length ${b.length}")
else
print("Empty string")
方法2 安全調(diào)用操作符
Kotlin 新增了一個(gè)安全調(diào)用操作符 ?. :
b?.length
如果當(dāng)b不為null時(shí)候就會(huì)返回b.length,否則返回null。
安全調(diào)用也適用于鏈?zhǔn)秸{(diào)用,比如:
bob?.department?.head?.name
其中的任何一個(gè)對(duì)象為null就會(huì)返回null。
如果你確定你要執(zhí)行的操作只針對(duì)非空對(duì)象,那么你可以?.配合let一起使用:
val listWithNulls: List<String?> = listOf("A", null)
for (item in listWithNulls) {
item?.let { println(it) } // prints A and ignores null
}
方法3 艾維斯操作符(名字有木有覺(jué)得略屌)
首先是普通青年的寫(xiě)法:
val l: Int = if (b != null) b.length else -1
文藝青年Kotlin寫(xiě)法之艾維斯操作符-----?: :
val l = b?.length ?: -1
這個(gè)操作符跟&&類(lèi)似,操作符左側(cè)滿(mǎn)足要求,就不再執(zhí)行右側(cè).
前方高能~~~~
這個(gè)操作符能直接把 throw 和 return 當(dāng)作表達(dá)式放在右側(cè):
fun foo(node: Node): String? {
val parent = node.getParent() ?: return null
val name = node.getName() ?: throw IllegalArgumentException("name expected")
// ...
}
方法4 !! 操作符
val l = b!!.length
要么返回b的長(zhǎng)度length,要么就一言不合拋出NPE
Kotlin之類(lèi)型轉(zhuǎn)換
java中類(lèi)型強(qiáng)轉(zhuǎn)一失敗就拋異常 ClassCastException, Kotlin友好多了,轉(zhuǎn)不成功給你個(gè) null:
val aInt: Int? = a as? Int
本節(jié)結(jié)尾總結(jié)一下:
Kotlin強(qiáng)大的操作符設(shè)計(jì)屏蔽了java最大的坑--NPE,而且整體使用上感覺(jué)非常舒服,建議java的小伙伴們都來(lái)試一試。
