异常处理机制
在 Kotlin 里,异常体系构建于 Throwable 之上。每个异常对象都携带消息、堆栈追踪信息以及可选的原因对象。抛出异常使用 throw 表达式:
throw MyException("Hi There!")
捕获异常则依赖 try-catch-finally 结构。这里有个关键点,try 是一个表达式而非语句,这意味着它可以返回值:
val a: Int? = try { parseInt(input) } catch (e: NumberFormatException) { null }
表达式的值由 try 块或 catch 块的最后一行决定,finally 块不会改变返回值。在 try 块中,catch 子句可以出现零次或多次,finally 也是可选的,但两者不能同时缺失。
检查异常的取舍
Kotlin 摒弃了检查异常(Checked Exceptions)。这么做主要是为了减少样板代码,避免像 JDK 中 StringBuilder.append() 那样强制调用者处理所有潜在异常的情况。虽然这减少了冗余,但也要求开发者更自觉地处理运行时风险。正如《Effective Java》所强调的,不应随意忽略异常。
Nothing 类型的妙用
throw 本身是表达式,返回类型为 Nothing。这个特殊类型表示该语句永远不会正常执行结束,常用于 Elvis 运算符中作为兜底逻辑:
val s = person.name ?: throw IllegalArgumentException("Name required")
编译器能据此推断后续代码的安全性。例如定义一个总是抛出的辅助函数:
fun fail(message: String): Nothing {
throw IllegalArgumentException(message)
}
调用时,编译器知道 s 在此处已被初始化。此外,Nothing? 仅包含 null 值,可用于类型推导场景,比如当使用 null 初始化未指明类型的变量时,编译器会将变量类型推导为 Nothing?。
与 Java 的互操作
Kotlin 异常系统与 Java 完全兼容,可以直接抛出和处理 Java 异常,反之亦然。具体细节可参考官方文档关于 Java 交互的部分。

