Kotlin系列之异常

这一节我们说说Kotlin中的异常。

Java中的异常

我们知道,在Java中,异常是一个绕不过的话题,说到异常,最先想到的就是try...catch...finally,在Kotlin中也是同样的,使用方式几乎是不变的,但是也有一些小小的变动。这里我们还是以往的惯例,先放Java代码,再上Kotlin代码。

Java代码

public int readNumber(BufferedReader reader) throws IOException {
    int result = 0;
    String line = reader.readLine();
    result = Integer.parseInt(line);
    reader.close();
    return result;
}

上面的代码readLine()方法会抛出IOException,这是一个受检查异常,必须要显式处理,要么在方法声明上抛出,要么在内部捕获处理。其实代码里面的parseInt()方法也会抛出一个运行时异常,Java是不强制要求我们捕获处理运行时异常的,但这里我们为了和后面的内容配合讲解,处理一下这个异常。
修改后的代码是这样。

Java代码

public int readNumber(BufferedReader reader) throws IOException {
    int result = 0;
    String line = reader.readLine();
    try {
        result = Integer.parseInt(line);
    }catch (NumberFormatException e){
        e.printStackTrace();
        result = -1;
    }finally {
        if (reader != null){
            reader.close();
        }
    }
    return result;
}

这里使用try...catch...finally来改善了一下代码。在Java中,一个函数可以正常结束,也会在出现错误的时候抛出异常,方法的调用者可以捕获这个异常并处理它,如果没有被处理,异常会沿着调用栈再次抛出。

Kotlin中throw作为表达式

在Kotlin中异常处理机制是相似的,但与Java中不同的是throw是一个表达式,可以作为另一个表达式的一部分使用。我们看看下面的代码。

Kotlin代码

fun test(){
    val n = 1;
    val res = if (n in 0..100){
        n
    }else{
        throw IllegalArgumentException("error")
    }

    println(res)
}

这里说一下,前面的内容也说过if也是表达式,上面的代码,如果n的值在0-100直接则res的值初始化为n的值,如果不是,抛出一个异常,res的值不初始化。与我们以前的代码一样,与Java语言不同,抛出的异常不需要使用new

Kotlin中的异常

我们在开始给出了一个Java中的try...catch...finally的例子,这里我们再使用Kotlin代码实现一下,对比一下两者的差异。

Kotlin代码

fun readNumber(reader: BufferedReader): Int{
    var result = 0
    val line = reader.readLine()
    try {
        result = Integer.parseInt(line)
    } catch (e: NumberFormatException) {
        e.printStackTrace()
        result = -1
    } finally {
        reader.close()
    }
    return result
}

上面的代码有几点需要注意。
1. 正如前面一直在说的,函数返回值类型是写在最后,用:分割。
2. 你会发现Kotlin中不需要显式在方法声明上声明抛出的IOException
3. 变量的声明也是变量名:变量类型的格式。

在Kotlin中不再区分受检查异常和不受检查异常。原因在于有时候比如我们的文件关闭出现错误的异常,除了看到这个异常,其实我们也做不了什么,Kotlin则直接将这种代码去掉了。
可能有的人还有疑问,在前面的java代码的finally块中有这样的的判空代码

if (reader != null){
    reader.close();
}

为什么在Kotlin中消失了?这是因为在Kotlin中声明函数参数类型时,如果这样写reader: BufferedReader,表示这是一个不可空值,如果要声明为可空值可以这样写reader: BufferedReader?,这样就需要在close前判空了。

Kotlin中的try作为表达式

前面我们说了throw作为表达式,其实try也是一个表达式,我们可以将try的值赋值给一个变量。我们继续该一下上面的代码。

Kotlin代码

fun readNumber(reader: BufferedReader): Int?{
    var result = 0
    val line = reader.readLine()
    result = try {
        Integer.parseInt(line)
    } catch (e: NumberFormatException) {
        e.printStackTrace()
        -1
    } finally {
        reader.close()
    }
    return result
}

你会发现代码又变少了,这里我们先补充一条规则才能理解上面的代码。
try作为表达式时,如果try块执行正常,则try块中最后一个表达式就是结果,如果抛出异常进入catch块,则catch块中最后一个表达式的值就是结果。
知道了这条规则是不是上面的代码就好理解了

写在最后

异常机制的出现是为了让我写出更加健壮的代码,在Kotlin中对Java的异常处理机制进行了一些改进和完善,让我们用更简洁的方式处理异常。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值