Kotlin异常详解
Kotlin 中所有异常类都是 Throwable 类的子孙类。 每个异常都有消息、堆栈回溯信息以及可选的原因。
使用 throw表达式来抛出异常:
fun main(args: Array<String>) {
throw Exception("exception ...")
}
使用 try-表达式来捕获异常:
try {
// 一些代码
}
catch (e: SomeException) {
// 处理程序
}
finally {
// 可选的 finally 块
}
可以有零到多个 catch 块。finally 块可以省略。 但是 catch 与 finally 块至少应该存在一个。
try 是一个表达式,即它可以有一个返回值:
val s = "3"
val result: Int? = try {
parseInt(s)
} catch (ex: NumberFormatException) {
null
} finally {
println("finally invoked")
}
try-表达式的返回值是 try 块中的最后一个表达式或者是catch 块中的最后一个表达式。 finally 块中的内容不会影响表达式的结果。
Kotlin 没有受检的异常。
以下是 JDK 中 StringBuilder
类实现的一个示例接口:
Appendable append(CharSequence csq) throws IOException;
这个签名是什么意思? 它是说,每次我追加一个字符串到一些东西(一个StringBuilder
、某种日志、一个控制台等)上时我就必须捕获那些IOException
。 为什么?因为它可能正在执行 IO 操作(Writer
也实现了 Appendable
)…… 所以它导致这种代码随处可见的出现:
ry {
log.append(message)
}
catch (IOException e) {
// 必须要安全
}
这并不好,参见《Effective Java》第三版 第 77 条:不要忽略异常。
在 Kotlin 中 throw
是表达式,所以你可以使用它(比如)作为 Elvis 表达式的一部分:
val str: String? = "a"
val str2 = str ?: throw IllegalArgumentException("值不能为空");
throw 表达式的类型是特殊类型 Nothing。 该类型没有值,而是用于标记永远不能达到的代码位置。 在你自己的代码中,你可以使用 Nothing 来标记一个永远不会返回的函数:
fun myMthod(message:String):Nothing{
throw IllegalArgumentException(message)
}
当你调用该函数时,编译器会知道执行不会超出该调用
val str3 = str ?: myMthod("hello")
println(str3)
可能会遇到这个类型的另一种情况是类型推断。这个类型的可空变体 Nothing? 有一个可能的值是 null。如果用 null 来初始化一个要推断类型的值,而又没有其他信息可用于确定更具体的类型时,编译器会推断出 Nothing? 类型:
val x = null // “x”具有类型 `Nothing?`
val l = listOf(null) // “l”具有类型 `List<Nothing?>
网友评论