Kotlin实战【五】Kotlin中的异常

一、kotlin如何抛异常

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

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

if(0 <= percentage <= 100){
  throw new IllegalArgumentException( "A percentage value must be between 0 and 100: $percentage") ;
}

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

if (percentage !in 0..100) {
    throw IllegalArgumentException( "A percentage value must be between 0 and 100: $percentage")
}

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

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。

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中:

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部分(因为你已经知道这个怎么工作),然后加一些代码打印从这个文件读取的数字。

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语句也需要一个值,这个值是最后表达式的值:

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代码块中最后一个表达式就是结果。

本文转自 https://cloud.tencent.com/developer/article/1397852,如有侵权,请联系删除。

相关视频:

Android进阶学习:Kotlin核心技术_哔哩哔哩_bilibili
Android网络架构搭建与原理解析(一)——通过一个网络请求一步一步见证网络模块的成长_哔哩哔哩_bilibili
【Android进阶课程】——colin Compose的绘制原理讲解(一)_哔哩哔哩_bilibili
【 Android进阶教程】——Framework面试必问的Handler源码解析_哔哩哔哩_bilibili
【 Android进阶教程】——热修复原理解析_哔哩哔哩_bilibili
【 Android进阶教程】——如何解决OOM问题与LeakCanary原理解析_哔哩哔哩_bilibili

上一篇:编译Android 4.4.2源码


下一篇:图片上传预加载