Kotlin 例外處理 (Exceptions)

Kotlin 的例外處理機制跟 Java 很像 (try, catch, throw),但有幾個關鍵的改進,讓程式碼更簡潔。

Try 是表達式 (Expression)

ifwhen 一樣,try 可以有回傳值! 這代表你可以把 try-catch 的結果直接指派給變數。

val a: Int? = try {
    input.toInt()
} catch (e: NumberFormatException) {
    null // 解析失敗回傳 null
}

沒有 Checked Exceptions

這是 Kotlin 與 Java 最大的不同點之一。 在 Java 中,你被強迫要捕捉或宣告 Checked Exceptions (例如 IOException)。 Kotlin 認為這導致了太多無意義的 boilerplate code,因此 Kotlin 沒有 Checked Exceptions

你不需要在函式後面寫 throws IOException,編譯器也不會強迫你一定要 try-catch。

Nothing 型別

如果一個函式 永遠不會回傳 (例如無窮迴圈,或是直接拋出例外),它的回傳型別是 Nothing

Nothing 是一個特殊的型別,它是所有型別的子類別。 這有什麼用?它可以用來做 Elvis Operator 的右邊!

val name = person.name ?: throw IllegalArgumentException("Name required")

因為 throw 表達式的型別是 Nothing,而 Nothing 是 String 的子類別,所以編譯器可以接受這行程式碼,並且推斷 name 一定是 String。

範例:fail 函式

你可以定義一個輔助函式來拋出錯誤:

fun fail(message: String): Nothing {
    throw IllegalArgumentException(message)
}

val s = person.name ?: fail("Name is required")

總結

  1. try 可以當表達式用。
  2. 沒有 Checked Exceptions (不用寫 throws)。
  3. 善用 Nothing 型別來處理錯誤流程。