Kotlin实战【五】Kotlin中的异常

一、kotlin如何抛异常

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

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

if
(
 <= 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


请使用浏览器的分享功能分享到微信等