⚠️ 例外處理
📖 什麼是例外?
**例外(Exception)**是程式執行過程中發生的錯誤。妥善處理例外可以讓程式不會中斷並穩定運作!
💡 基本 try-catch
基本用法
fun main() {
try {
val result = 10 / 0 // 錯誤發生!
println(result)
} catch (e: Exception) {
println("錯誤發生:${e.message}")
}
// 錯誤發生:/ by zero
println("程式繼續執行!")
}
處理特定例外
fun main() {
try {
val text = "abc"
val number = text.toInt() // NumberFormatException
} catch (e: NumberFormatException) {
println("無法轉換為數字:${e.message}")
} catch (e: Exception) {
println("未知錯誤:${e.message}")
}
}
finally
fun main() {
try {
println("開始作業")
// 執行作業
} catch (e: Exception) {
println("發生錯誤")
} finally {
println("清理作業(總是執行)")
}
}
🎯 實戰範例
安全的數字轉換
fun safeToInt(text: String): Int? {
return try {
text.toInt()
} catch (e: NumberFormatException) {
null
}
}
fun main() {
println(safeToInt("123")) // 123
println(safeToInt("abc")) // null
val age = safeToInt("25") ?: 0
println("年齡:$age")
}
檔案讀取模擬
class FileReader {
fun readFile(filename: String): String {
if (filename.isEmpty()) {
throw IllegalArgumentException("檔案名稱為空")
}
if (!filename.endsWith(".txt")) {
throw IllegalArgumentException("僅支援文字檔案")
}
return "檔案內容:$filename"
}
}
fun main() {
val reader = FileReader()
try {
val content = reader.readFile("data.txt")
println(content)
} catch (e: IllegalArgumentException) {
println("錯誤:${e.message}")
}
try {
reader.readFile("")
} catch (e: IllegalArgumentException) {
println("錯誤:${e.message}")
// 錯誤:檔案名稱為空
}
}
使用者輸入 驗證
data class User(val name: String, val age: Int)
fun createUser(name: String, age: Int): User {
require(name.isNotBlank()) { "姓名為必填" }
require(age > 0) { "年齡必須為正數" }
require(age < 150) { "年齡過大" }
return User(name, age)
}
fun main() {
try {
val user1 = createUser("洪吉童", 25)
println(user1)
val user2 = createUser("", 25) // 錯誤!
} catch (e: IllegalArgumentException) {
println("驗證失敗:${e.message}")
// 驗證失敗:姓名為必填
}
}
API 回應處理
sealed class Result<out T> {
data class Success<T>(val data: T) : Result<T>()
data class Error(val exception: Exception) : Result<Nothing>()
}
fun divide(a: Int, b: Int): Result<Int> {
return try {
Result.Success(a / b)
} catch (e: ArithmeticException) {
Result.Error(e)
}
}
fun main() {
val result1 = divide(10, 2)
when (result1) {
is Result.Success -> println("結果:${result1.data}")
is Result.Error -> println("錯誤:${result1.exception.message}")
}
val result2 = divide(10, 0)
when (result2) {
is Result.Success -> println("結果:${result2.data}")
is Result.Error -> println("錯誤:${result2.exception.message}")
}
}