Null
非空值類型
在宣告變數時就能確定它是有值的,不能是null,若把變數設為null,會編譯錯誤。
非空值類型「不可以」儲存 null 值的變數。
1
2
3
var name: String = "Tom"
//null不能是非空值類型字符串的值 編譯錯誤
//name = null
空值類型
空值類型,是「可以」儲存 null 值的變數。
官方建議,用var宣告。
類型後面加上?,類型不可省略。
var 變數名:類型?
代表此變數「可以」儲存 null 值。
1
2
var b: String? = "Tom"
b = null
這個變數的值有二種情況:值或null
使用這個變數時就必須額外檢查null,否則編譯器不會讓這個程式碼通過
存取空值變數的屬性
Kotlin 編譯器會對可為空值類型強制執行「null 檢查」。
以下程式碼會編譯失敗,因為沒有檢查空值類型。
1
2
var b: String? = "Tom"
println(b.length)
if null
在檢查的範圍內,可以使用變數的屬性。
1
2
3
4
var b: String? = "Tom"
if (b != null) {
println(b.length)
}
3
這樣做更好,若為null,就傳回0
1
2
3
4
5
6
7
var b: String? = "Tom"
var result = if (b != null) {
b.length
} else {
0
}
println(result)
安全呼叫?.
使用?.符號來安全呼叫成員屬性。
1
2
3
var b: String? = "Tom"
//如果B有值就存取它的length屬性
println(b?.length)
3
安全呼叫?.存取null屬性
即使嘗試存取 null 變數的 length 屬性,該程式仍不會停止運作。安全呼叫運算式只會傳回 null。
語法
?.method
1
2
var b: String? = null
println(b?.length)
null
貓王(Elvis)運算子?:
什麼是貓王(Elvis)運算子?:
物件是null,傳回預設值。
變數 ?: 預設值
存取null物件的屬性,需搭配安全呼叫?.
變數?.屬性 ?: 預設值
1
2
3
var name2:String? = null
println(name2 ?: "no data")
println(name2?.length ?: "no data")
no data
no data
使用了一個安全呼叫?.後面的呼叫也必須使用安全呼叫,有一個呼叫是null,後面的安全呼叫就都不執行。
1
2
val name3: String? = null
println(name3?.uppercase()?.replace("T","J")?.length ?: "name 3 is null")
name 3 is null
let安全呼叫
即使嘗試存取 null 變數,該程式仍不會停止運作,安全呼叫運算式只會傳回 null。
若不為null,才會執行let{} Lambda函式,否則傳回null。
1
2
val name3: String? = null
println(name3?.let { if (name3.isNotBlank()) name3 else "blank" })
null
強制呼叫!!
確定有值,用在可為空值類型的變數,不打算使用安全呼叫,使用雙驚嘆號!!
語法
!!.method
若變數是null,就會產生 Exception in thread “main” java.lang.NullPointerException
1
2
var c: String? = "Tom"
println(c!!.length)