Kotlin教學 | 從零開始學Kotlin | Kotlin入門 | CH03: 空安全(Null Safety)

空安全(Null Safety)

在 Kotlin 中,空安全(Null Safety) 是一項設計特性,用於避免在運行時發生 NullPointerException(NPE)。

Kotlin 通過明確地將變量分為可空(nullable)與不可空(non-nullable)來實現空安全。


1. 不可空型別

  • 預設情況下,Kotlin 的變量不能為 null
  • 如果嘗試將 null 賦值給不可空變量,會導致編譯錯誤。

範例

var name: String = "Kotlin"
// name = null // 編譯錯誤:`null` 無法賦值給非空型別

2. 可空型別

  • 如果變量需要接受 null 值,可以在型別後加上 ? 來聲明為可空型別。
  • 可空型別允許變數的值為 null

範例

var name: String? = "Kotlin" // 可空變量初始值為 "Kotlin"
name = null // 將變量的值設為 null
println(name) // 輸出 null

3. 安全調用操作符(?.

  • 用途:在調用可空變量的屬性或方法時,使用 ?. 可以安全地執行操作。如果變量為 null,結果會直接返回 null,而不會拋出異常。

範例

var a: String? = null // 可空變量初始值為 null
println(a?.length) // 安全調用,輸出 null,因為 a 為 null

a = "Kotlin" // 將 a 賦值為 "Kotlin"
println(a?.length) // 安全調用,輸出 6,因為 "Kotlin" 的長度為 6

4. Elvis 操作符(?:

  • 用途:提供一個替代值,如果變量為 null,則返回替代值。

範例

val name: String? = null
val length = name?.length ?: 0 // 如果 name 不為 null,返回length,如果為 null,則返回 0
println(length) // 輸出 0

5. 非空斷言操作符(!!

  • 用途:告訴編譯器變量一定不為 null
  • 注意:如果變量實際為 null,將拋出 NullPointerException

範例

val name: String? = null
// println(name!!.length) // 執行時會拋出 NullPointerException

6. 可空型別的條件檢查

在操作可空型別前,可以使用條件檢查來避免 NPE。

範例

val name: String? = null
if (name != null) {
    println(name.length) // 在這裡可以安全地使用 name
} else {
    println("name is null")
}

7. let 函數與空安全

  • 用途let 函數常與 ?. 結合,用於執行非空情況下的操作。

範例

val name: String? = "Kotlin"
name?.let {
    println("Name length: ${it.length}") // 如果 namenulllet 內部的程式碼不會執行。
}

8. 使用泛型與空安全

Kotlin 的泛型也支持空安全檢查。例如,處理列表時可以明確指定元素是否可為 null

範例

val list: List<String?> = listOf("Kotlin", null, "Java")
for (item in list) {
    println(item?.uppercase() ?: "Unknown") // 安全處理每個元素
}

9. 預防 NullPointerException 的關鍵

Kotlin 內建的空安全特性大大減少了 NullPointerException,但在以下情況下可能仍會發生:

  1. 使用 !! 非空斷言時。
  2. 與 Java 程式碼交互時。
  3. 錯誤地初始化變量(例如,lateinit 屬性未初始化)。

Reference

https://kotlinlang.org/docs/null-safety.html

發佈留言