美文网首页
每天学一点 Kotlin -- 对象进阶:异常处理

每天学一点 Kotlin -- 对象进阶:异常处理

作者: 冯可乐同学 | 来源:发表于2021-12-01 09:20 被阅读0次

    ----《第一季Kotlin崛起:次世代Android开发 》学习笔记

    总目录:每天学一点 Kotlin ---- 目录
    上一篇:每天学一点 Kotlin -- 对象进阶:对象类型
    下一篇:每天学一点 Kotlin -- 对象进阶:对象比较

    1. 异常

    1.1 跟Java中相同,程序中逻辑不对时,在运行时也会报错,举个栗子:

    fun testE1() {
        val s = "123"
        println(s.toInt())
    
        val s1 = "abc"
        println(s1.toInt()) //java.lang.NumberFormatException: For input string: "abc"
    }
    
    fun main() {
        testE1()
    }
    

    打印结果:

    123
    Exception in thread "main" java.lang.NumberFormatException: For input string: "abc"
        at java.base/java.lang.NumberFormatException.forInputString(NumberFormatException.java:65)
        at java.base/java.lang.Integer.parseInt(Integer.java:652)
        at java.base/java.lang.Integer.parseInt(Integer.java:770)
        at chapter07.TestExceptionKt.testE1(TestException.kt:9)
        at chapter07.TestExceptionKt.main(TestException.kt:13)
        at chapter07.TestExceptionKt.main(TestException.kt)
    

    从打印结果可知,字符串里面不符合数字格式时,字符串转换为数字就会报错,并抛出异常:NumberFormatException。

    1.2 跟Java中相同,使用try-catch(finally)语句块。举个栗子:

    fun testE2(i: Int, str: String): Int {
        try {
            val a = 10 / i
            val s = str.toInt()
            return s
        } catch (e: Exception) {
            when (e) {
                is ArithmeticException -> println("除数不能为0")
                is NumberFormatException -> println("不是正确的数字格式")
                else -> println("未知错误")
            }
    
            return 0
        } finally {
            println("函数执行完毕")
        }
    }
    
    fun main() {
        println("result1 = " + testE2(0,"123"))
        println("result2 = " + testE2(0, "abc"))
        println("result3 = " + testE2(2, "123"))
        println("result4 = " + testE2(2, "abc"))
    }
    

    打印结果:

    除数不能为0
    函数执行完毕
    result1 = 0
    除数不能为0
    函数执行完毕
    result2 = 0
    函数执行完毕
    result3 = 123
    不是正确的数字格式
    函数执行完毕
    result4 = 0
    

    2. 自定义异常

    2.1 ArithmeticException 和 NumberFormatException 这两个异常都是系统自带的,也可以自定义异常

    2.2 自定义异常继承于系统的异常类。一般是继承自 Exception,举个栗子:

    class MyException(msg: String) : Exception(msg) {}
    
    fun testE3() {
        var userName = "xiaoMing"
        try {
            if (userName != "xiaoHong") {
                throw MyException("用户名错误")
            }
        } catch (e: Exception) {
            if (e is MyException) {
                println(e.message)
            }
        } finally {
            println("用户名判断完毕")
        }
    }
    
    fun main() {
        testE3()
    }
    

    打印结果:

    用户名错误
    用户名判断完毕
    

    2.3 上面的代码中使用 throw 关键字抛出异常,throw 后面要跟上需要抛出的异常的实例对象。

    2.4 t对于 hrow 表达式,其实它的类型是 Nothing,该类型没有值,而是用于标记永远不能达到的代码位置。在代码中可以用 Nothing 标记一个永远不会返回的函数。举个栗子:

    fun errorAppear(msg: String): Nothing{
        throw ErrorException(msg)
    }
    

    为什么说没有返回呢?因为它到头来是抛出一个异常,而不是一个真实的值。

    3. 必检异常

    3.1 在 Kotlin 中,处理异常的方式与 Java 中几乎一模一样,只有一条关键不同:就是 Kotlin 中所有的异常都是非必检的。

    3.2 所谓必检异常,是指必须定义成方法的一部分或者在方法内部处理。一个经典的例子就是 IOException,可以被很多文件处理相关的函数抛出,因此在很多地方最终通过 IO 库来定义它。

    3.3 非必检异常是指没有什么必要加入到方法中的异常。在 Kotlin 中,因为所有异常都是非必检的,所以异常不必成为函数的组成部分。

    3.4 举个栗子:
    (1) 写法一:
    fun readFile(path: Path): Unit{
    val input = Files.newInputStream(path)

    var bytes = input.read()
    while(bytes != -1){
        println(bytes)
        bytes = input.read()
    }
    

    }
    不处理异常,编译器不会报错

    (2) 写法二:
    fun readFile(path: Path): Unit {
    val input = Files.newInputStream(path)

    try {
        var bytes = input.read()
        while (bytes != -1) {
            println(bytes)
            bytes = input.read()
        }
    } catch (e: IOException) {
        println("读取文件错误,因为: ${e.message}")
    } finally {
        input.close()
    }
    

    }
    像 Java 中一样,使用try,catch,finally 代码块处理异常

    相关代码:https://gitee.com/fzq.com/test-demo

    相关文章

      网友评论

          本文标题:每天学一点 Kotlin -- 对象进阶:异常处理

          本文链接:https://www.haomeiwen.com/subject/ujytaltx.html