IT评测·应用市场-qidao123.com
标题:
Kotlin 抛出和捕获异常(十一)
[打印本页]
作者:
海哥
时间:
2024-11-28 16:46
标题:
Kotlin 抛出和捕获异常(十一)
1.1 在 Kotlin 中抛出和捕获异常
Kotlin 中的异常处置惩罚
类似于 Java 和许多其他语言中的处置惩罚方式
函数可以正常完成,也可以
在发生错误时抛出异常
函数的调用者
可以
捕获异常并举行处置惩罚
假如不捕获,
异常会被重新抛出到堆栈的更上层
可以使用 throw 关键字抛出异常
<1> 在本例中,表示
调用函数提供一个无效的百分比值
Kotlin 没有 new 关键词
, 创建异常实例也是如此
if (percentage !in 0..100) { // <1>
throw IllegalArgumentException( // <1>
"A percentage value must be between 0 and 100: $percentage"
)
}
复制代码
在 Kotlin 中,
throw 结构是一个表达式
<1> throw 是一个表达式, 可
作为其他表达式的一部分
使用
假如条件满足, 程序将正常运行
并
用 number 初始化 percentage 变量
否则,
程序将抛出异常
,
变量不会被初始化
关于表达式与语句的区别–传送门
val percentage =
if (number in 0..100)
number
else
// <1>
throw IllegalArgumentException("A percentage value must be between 0 and 100: $number"
)
复制代码
1.1.1 处置惩罚异常和从错误中恢复: try、catch 和 finally
试图从错误中恢复,而不是抛出异常
可以
使用带有 catch 和 finally 子句的 try 结构
来
处置惩罚异常
<1> 它
从 BufferedReader 中读取一行文本
,尝试
将其分析为一个数字
假如
该行不是一个有用的数字
则
返回null
反之是有用数字, 则会返回分析后的数值
<2> 在 Kotlin 中, 您
无法明确指定函数可以抛出的异常
import java.io.BufferedReader
import java.io.StringReader
fun readNumber(reader: BufferedReader): Int? { // <2>
try {
val line = reader.readLine() // <1>
return Integer.parseInt(line) // <1>
} catch (e: NumberFormatException) {
return null // <1>
} finally {
reader.close()
}
}
fun main() {
val reader = BufferedReader(StringReader("239")) // <1>
println(readNumber(reader))
// 239
}
复制代码
与 Java 的一个重要区别
是,
Kotlin 没有 throws 子句
<1> 假如用Java写这个函数,会
在函数声明后明确写入throws IOException
在 Java 中,
查抄异常是方法签名的一部分
您需要如许做,因为
Java 的 readLine 和 close 大概会抛出 IOException
这是一种经过查抄
的异常
在 Java 世界中,这是一种
需要明确处置惩罚的异常类型
您
必须声明您的函数
显式
指定全部经过查抄的异常
*
假如您调用另一个函数
需要
处置惩罚它显式指定的异常
或
声明函数也可以抛出这些异常
Integer readNumber(BufferedReader reader) throws IOException // <1>
复制代码
就像许多其他当代 JVM 语言一样, Kotlin
不区分查抄异常和未查抄异常
您可以
不指定函数抛出的异常
,也可以
不处置惩罚任何异常
这一计划决策
基于 Java 中
使用查抄(checked)异常的实践
履历表明,
Java 规则
往往
需要大量偶然义的代码
来
重新抛出或忽略异常
这些规则并
不能始终如一地保护
您
免受大概发生的错误的影响
例如,在上述示例中,NumberFormatException 并
不是一个经过查抄的异常
因此,
Java编译器不会逼迫您捕获它
你可以
在运行时轻松地看到异常发生
这是很不幸的,因为
无效的输入数据是一种常见的环境
,应该从容应对
同时,
BufferedReader.readLine方法
会
抛出一个IOException异常
这是一个
经过查抄的异常
,
需要加以处置惩罚
假如流关闭,大多数程序都
无法采取任何有意义的操作
因此
捕获流操作方法的IOException
异常
所需的代码都是模板化
的
由于这一计划决策,您可以
自行决定要处置惩罚
或
不要处置惩罚哪些异常
<1> 假如你乐意,
完全可以不使用任何 try-catch 结构
来实现 readNumber 函数
在 Kotlin 中,
编译器不会逼迫您处置惩罚异常
fun readNumber(reader: BufferedReader): Int {
val line = reader.readLine() // <1>
reader.close()
return Integer.parseInt(line)
}
复制代码
那么 Java 的 try-with-resources 呢?
Kotlin
对此没有任何特殊语法
, 它是
作为库函数实现的
1.1.2 使用 try 作为表达式
到目前为止,你
只看到 try 结构作为语句使用
但是,由于 try 是一个表达式(就像 if 和 when 一样)
<1> 利用这一点,
将 try 表达式的值赋值给一个变量
fun readNumber(reader: BufferedReader): Int? {
val number = try { // <1>
Integer.parseInt(reader.readLine())
}catch (e: NumberFormatException) {
return null
}finally {
reader.close()
}
}
复制代码
值得注意的是,与 if 差别,即使块体只包罗一个表达式,
大括号也是不能省略
的
与其他语句一样,假如
主体包罗多个表达式
则
整个 try 表达式的值
就是
最后一个表达式的值
代码块中的最后一个表达式即为结果–传送门
上面示例
在 catch 代码块中参加 return 语句
因此
函数不会在 catch 代码块之后继续执行
<1> 假如要继续执行,
catch 子句也作为表达式
即这里的
null作为catch表达式的值
赋值给 number 变量
fun readNumber(reader: BufferedReader): Int? {
val number = try {
Integer.parseInt(reader.readLine())
}catch (e: NumberFormatException) {
null // <1>
}
println("number: $number")
return number
}
复制代码
假如 try 代码块的执行环境正常,则
该代码块中的最后一个表达式就是结果
假如捕获异常,
相应 catch 代码块中的最后一个表达式
也是结果
使用 try 作为表达式
,可以
避免引入额外的中间变量
还可以
分配回退值(catch作为表达式)
或直接
从外层函数返回(在catch中return)
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。
欢迎光临 IT评测·应用市场-qidao123.com (https://dis.qidao123.com/)
Powered by Discuz! X3.4