Kotlin 的异常处理(exception handling)与 Java 相似,但有重要区别。Kotlin 使用熟悉的结构 try、catch 和 finally,但根本区别在于 Kotlin 没有 checked exceptions。这意味着所有异常(运行时错误)都被视为 unchecked — 不需要在函数签名中声明它们,也不需要显式捕获。
finally 块总是会执行,即使抛出了异常。try 的 "return value",即 try 可以作为表达式使用,返回结果。try/catch 来进行流程控制 — 仅在真正异常的情况下使用。fun parseIntOrNull(str: String): Int? = try { str.toInt() } catch (e: NumberFormatException) { null }
use 进行 "resource management" 以进行自动关闭(例如文件)。在 Kotlin 中,是否需要在函数签名中指定它所抛出的异常(如 Java 中的 throws)?
正确答案: 不,在 Kotlin 中没有 checked exceptions 的机制。所有异常都是 unchecked。函数签名中没有 throws 的语法(异常 — 注解 @Throws 用于与 Java 的兼容性,仅用于互操作)。
故事
在项目中,我们将使用 checked exceptions 的 Java 代码(例如
IOException)迁移到 Kotlin。在迁移到 Kotlin 后,开发人员忘记在处理文件时捕获异常 — 应用程序在处理真实文件时开始崩溃,因为没有人处理 IO 错误,以为编译器会像在 Java 中那样发出警告。
故事
团队中的一个成员错误地使用 try/catch 进行流程控制,导致日志解析速度变慢(对于每个无效字符串捕获 NumberFormatException — 在大量数据情况下性能急剧下降)。
故事
在一个为 JVM 的项目中,通过 Kotlin 调用了声明了 checked exceptions (
throws) 的 Java 代码。Kotlin 代码没有处理异常,以为 "一切都是 unchecked" — 结果,一个关键错误在生产事故之前没有被注意到。