Kotlin 中的错误处理:try/catch 与进阶技巧

面向初学者的在线Python训练器

轻松学习Python,无需理论负担。在浏览器中直接解决带自动检查的实践任务,无需安装任何东西。

开始课程

Kotlin中的错误处理:try/catch 与更多方法



错误处理是编写可靠健壮代码的重要组成部分。与 Java 一样,Kotlin 提供了经典的 try/catch/finally 机制,但该语言还提供了更现代的函数式方法。本文将深入探讨 Kotlin 中处理异常的所有方式:从基础的 try/catch 到优雅的 runCatching 以及强大的 Result 和 sealed class。



1. 经典的 try/catch/finally

Kotlin 中异常处理的基本语法与 Java 几乎相同,但有一个重要区别:try 可以作为一个表达式使用,这意味着它可以返回一个值。



示例 1:try 作为表达式

fun parseIntOrNull(input: String): Int? {    return try {        input.toInt()    } catch (e: NumberFormatException) {        null    }}

fun main() { val result = parseIntOrNull("123") println(result) // 123

val badResult = parseIntOrNull("abc") println(badResult) // null}


示例 2:多个 catch 块

fun processInput(input: String) {    try {        val number = input.toInt()        val result = 100 / number        println("Result: $result")    } catch (e: NumberFormatException) {        println("Error: invalid number format")    } catch (e: ArithmeticException) {        println("Error: division by zero")    } finally {        println("The finally block always executes")    }}


finally 块在任何情况下都会执行——无论执行成功还是发生异常。这对于释放资源(关闭文件、连接)非常方便。



2. Elvis 运算符 (?:) 与安全调用

Kotlin 提供了一种优雅的方式来处理 null 值,这通常有助于避免繁琐的 try/catch 结构。



示例:使用 Elvis 运算符进行安全转换

fun safeStringToInt(input: String): Int {    return input.toIntOrNull() ?: 0 // 如果为 null,则返回 0}

fun main() { println(safeStringToInt("42")) // 42 println(safeStringToInt("abc")) // 0}


toIntOrNull() 函数是 Kotlin 内置的 try/catch 替代方案。它不会抛出异常,而是在出错时返回 null。Elvis 运算符 ?: 用于提供一个默认值。



3. 函数式方法:runCatching 和 Result

现代 Kotlin 推荐使用函数式风格进行错误处理。核心工具是 runCatching 和 Result 类。



示例:runCatching

import kotlin.Result

fun divide(a: Int, b: Int): Result<Int> { return runCatching { a / b }}

fun main() { val successResult = divide(10, 2) val failureResult = divide(10, 0)

// 处理结果 successResult .onSuccess { println("Success: $it") } // Success: 5 .onFailure { println("Error: ${it.message}") }

failureResult .onSuccess { println("Success: $it") } .onFailure { println("Error: ${it.message}") } // Error: / by zero

// 使用默认值获取结果 val value1 = successResult.getOrDefault(-1) // 5 val value2 = failureResult.getOrDefault(-1) // -1

// 转换结果 val mappedResult = successResult.map { it * 2 } // Result(10)}


runCatching 的优点:

  • 代码更具声明性和可读性。
  • 无需手动编写 try/catch。
  • 结果可以轻松地通过调用链(.map 等)进行组合、转换和处理。

博客

书籍推荐