学习
实践
活动
工具
TVP
写文章
专栏首页伟大程序猿的诞生Kotlin实战【五】Kotlin中的异常

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://blog.csdn.net/github_33304260复制
如有侵权,请联系 cloudcommunity@tencent.com 删除。
登录 后参与评论
0 条评论

相关文章

  • Kotlin实战【六】Kotlin中集合的创建

    public interface Collection<out E> : Iterable<E>{...}

    先知先觉
  • Kotlin中单利常用的五种写法

    单利模式是写代码过程中不可避免用到的,下面我总结一下单利常用的五种写法,话不多说了,来一起看看详细的介绍吧

    砸漏
  • Kotlin中单利常用的五种写法

    单利模式是写代码过程中不可避免用到的,下面我总结一下单利常用的五种写法,话不多说了,来一起看看详细的介绍吧

    PHP开发工程师
  • About Kotlin-Kotlin中的类2About Kotlin(2)

    使用sealed修饰符修饰。其实是一组类的集合。可以用来表示受限的类的继承结构。 其也可以有子类,所有子类也必须在相同的文件中声明。 密封类从某种意义上说,...

    deep_sadness
  • About Kotlin-Kotlin中的类1About Kotlin(1)

    因为是从Java的角度来学习Kotlin,在Java中,类作为第一等公民。故学习Kotlin,也先从其的类开始。

    deep_sadness
  • Kotlin中的函数

    函数还可以用中缀表示法调用,当他们是成员函数或扩展函数,只有一个参数,用 infix关键字标注

    deep_sadness
  • Kotlin中的扩展

    Kotlin 的扩展是一个很独特的功能, Java 本身并不支持扩展, Kotlin 为了让扩展能在JVM平台上运行,必须做一些独特的处理

    对话、
  • Kotlin中级(5)- - - 初识Kotlin中的对象.md

    主构造和次构造可以并存么?当然可以。但是如果类有一个主构造函数,那么每个次构造函数都需要委托给主构造函数。也就是说,次构造函数在最后还是要用到主构造函数。

    Hankkin
  • Kotlin 设计模式及实战 (持续更新中......)

    面向对象的设计原则也被称为SOLID。在设计和开发软件时可以应用这些原则,以便创建易于维护和开发的程序。SOLID最初是由Robert C.Martin所提出的...

    一个会写诗的程序员
  • Kotlin的枚举与异常示例详解

    比如BufferReader.close可能会抛出IOException异常,但很多程序对这个异常都不会采取有意义的行动,所以对这个异常的捕获所写的代码就是冗余...

    砸漏
  • 浅谈Kotlin(五):data class的使用

    使用data class的一大好处就是不用自己写一堆toString()方法的代码了。

    听着music睡
  • Kotlin中的内联函数

    lambda 表达式会被正常地编译成匿名类。这表示每调用一次 lambda表达式,一个额外的类就会被创建。 并且如果 lambda捕捉了某个变量, 那么每次调用...

    对话、
  • 浅谈Kotlin中的函数

    Kotlin,已经被Android官方宣布 kotlin first 的存在,去翻 Android 官方文档的时候,发现提供的示例代码已经变成了 Kotlin。...

    2020labs小助手
  • 聊聊Kotlin中的lambda

    将lambda定义的方法变成一个function类,其invoke方法体内容也就是lambda的方法体。

    用户7528483
  • 浅析 Kotlin 中的 synchronized

    首先,在 Java 中 synchronized 是一个关键字,在Kotlin 中是一个函数。这个函数如下:

    一个会写诗的程序员
  • Android 开发中 Kotlin Coroutines 如何优雅地处理异常

    GlobalScope 是 CoroutineScope 的实现类。我们以前使用过的 launch、async 函数都是 CoroutineScope 的扩展...

    fengzhizi715
  • Kotlin中?和!!的区别

    很多同学刚上手使用Kotlin知道它有针对Java NullPointerException的管理,而在Kotlin中?和!!均是和NullPointerExc...

    乱码三千

扫码关注腾讯云开发者

领取腾讯云代金券