前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Kotlin实战【五】Kotlin中的异常

Kotlin实战【五】Kotlin中的异常

作者头像
先知先觉
发布2019-03-04 11:11:11
1.9K0
发布2019-03-04 11:11:11
举报

一、kotlin如何抛异常

Kotlin中的异常处理与Java或者其他语言中的处理方式相似。一个函数可以以正常方式结束,或者当错误发生的时候抛出异常。函数调用者捕获这个异常并处理它;如果没有,异常重新在调用栈向上抛。

Kotlin中的异常处理语句的基本形式和Java是相似的: java中:

代码语言:javascript
复制
if(0 <= percentage <= 100){
  throw new IllegalArgumentException( "A percentage value must be between 0 and 100: $percentage") ;
}

kotlin中:(和java的区别,不必使用new来创建实例)

代码语言:javascript
复制
if (percentage !in 0..100) {
    throw IllegalArgumentException( "A percentage value must be between 0 and 100: $percentage")
}

不光如此,kotlin中的throw结构是一个表达式,能作为另一个表达式的一部分使用:

代码语言:javascript
复制
val percentage =
    if (number in 0..100)
        number
    else
        throw IllegalArgumentException( //“throw” 是一个表达式
            "A percentage value must be between 0 and 100: $number")

这个例子中,如果满足条件,程序的行为正确,percentage会number初始化,否则异常将被抛出,而变量也不会初始化。

二、“try”、“catch”、“finally”

就像Java之中,可以用try结构,和catch和finally子句处理异常。

如下,读取指定文件的一行,尝试解析为数字,然后返回一个数字,如果这行不是有效的数字,返回null。

代码语言:javascript
复制
fun readNumber(reader: BufferedReader): Int? { //不必显式地指定这个函数可能抛出的异常
    try {
        val line = reader.readLine()
        return Integer.parseInt(line)
    } catch (e: NumberFormatException) { //异常的类型在右边
        return null
    } finally { //finally就像在Java一样的
        reader.close()
    }
}
val reader = BufferedReader(StringReader("239"))
println(readNumber(reader))
//239

java中:

代码语言:javascript
复制
public int readNumber(BufferedReader reader) throws IOException{ //显式地指定这个函数可能抛出的异常
  try {
      String line = reader.readLine()
      return Integer.parseInt(line)
  } catch (NumberFormatException e) {
      return null
  } finally {
      reader.close()
  }
}

从对比中我们可以看出kotlin和Java最大的不同是不需要throws子句。在java中,这种异常必须显示的处理,必须声明你的函数可能抛出的所有受检异常。 如果调用另一个函数,需要处理这个函数的受检异常,或者声明你的函数可能抛出的这些异常。

和其他现代JVM语言,Koltin不区别受检查和不受检查的异常。你需要指定一个函数抛出的异常,你可以也可以不处理这些异常。这个设计决定是基于Java中使用受检查异常的实践。经验表明,Java规则常常需要很多无意义的代码从新抛出或者忽略异常,而且这些规则不能总是保护你免受坑你发生的错误。

在上面的例子中,NumberFormatException是一个不受检查的异常。所以Java编译器不会强迫你捕获这个异常,你可以很容易的看见运行时的异常。这相当令人遗憾,因为不有效的输入数据是经常的事情,应该更优雅的处理。同时,BufferedReader.close方法也能抛出一个IOException异常,这是个需要处理的受检查的异常。如果关闭一个流失败了,大部分代码不能采取任何有意义的行动,所以需要从close方法捕获异常的代码基本是样板代码。

三、try作为一个表达式

为了显示Java和Kotlin直接一个重要区别,让我们稍微改变下这个例子。移除fianlly部分(因为你已经知道这个怎么工作),然后加一些代码打印从这个文件读取的数字。

代码语言:javascript
复制
fun readNumber(reader: BufferedReader) {
    val number = try {
        Integer.parseInt(reader.readLine()) //成为try表达式的值
    } catch (e: NumberFormatException) {
        return
    }
    println(number)
}

val reader = BufferedReader(StringReader("not a number"))
readNumber(reader)//没有打印任何数字

Kotlin中try关键词,就像if和when,引进了一个表达式,你可以把它的值赋值给一个变量。不像if,你一直需要把语句保函在花括号中。就像其他语句,如果包涵多个表达式,try表达式的值是最后一个表达式的值。在这个例子中,在catch代码块中有return语句,所以这个函数在catch代码块后不会再进行。如果你想继续这个执行,catch语句也需要一个值,这个值是最后表达式的值:

代码语言:javascript
复制
fun readNumber(reader: BufferedReader) {
    val number = try {
        Integer.parseInt(reader.readLine()) //没有异常发生时使用这个值
    } catch (e: NumberFormatException) {
        null //异常发生时使用null值
    }
    println(number)
}
val reader = BufferedReader(StringReader("not a number"))
readNumber(reader)//异常被抛出,所以函数打印null
//null

如果一个try代码块执行一切正常,代码块中最后一个表达式就是结果。如果捕获到一个异常,那么cache代码块中最后一个表达式就是结果。

四、总结

  • 1、kotlin中的异常处理和java处理相似,除了Kotlin不要求你声明函数可以抛出的异常。
  • 2、如果一个try代码块执行一切正常,代码块中最后一个表达式就是结果。
  • 3、如果捕获到一个异常,那么cache代码块中最后一个表达式就是结果。
本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2019年02月13日,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 一、kotlin如何抛异常
  • 二、“try”、“catch”、“finally”
  • 三、try作为一个表达式
  • 四、总结
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档