美文网首页
Kotlin空类型安全处理总结

Kotlin空类型安全处理总结

作者: 翻译不了的声响 | 来源:发表于2019-03-22 15:07 被阅读0次

    在很多编程语言中 NullPointerException (NPE) 是最常见的异常之一,在 Java 中 NPE 就是空引用,引用空对象时出现的空指针异常,该异常在源程序中可以不进行捕获和处理。在Kotlin语言中解决了这个空异常问题,下面来看看它是怎样做到空安全的。

    空指针异常

    Kotlin 官方文档给出了 NPE 可能出现的原因:

    • 显式调用throw NullPointerException()

    • 使用了下文描述的!!操作符;

    • 有些数据在初始化时不一致,例如当:

    • Java 互操作:

      • 企图访问平台类型null引用的成员;
      • 用于具有错误可空性的 Java 互操作的泛型类型,例如一段 Java 代码可能会向 Kotlin 的MutableList<String>中加入null,这意味着应该使用MutableList<String?>来处理它;
      • 由外部 Java 代码引发的其他问题。
    1. 空的类型

    Kotlin 空类型分为:可空类型非空类型

    • 非空类型
      常规变量不能容纳 null;
    fun main() {
        var a: String = "abc"
        a = null // 编译错误
    }
    
    • 可空类型
      使用?操作符声明可空类型,避免抛出 NPE;
    fun main() {
        var b: String? = "abc"
        b = null // ok
        println(b) // 输出 null
    }
    
    2. 空的安全调用

    1)使用?.操作符安全调用,避免抛出 NPE;

    fun main() {
        var a = "abc"
        var b :String? = null
        println(a?.length) // 无需安全调用
        println(b?.length) // 输出 null
    }
    

    如果 b 非空,就返回 b.length,否则返回 null,这个表达式的类型是 Int?。

    2)使用操作符?.let一起使用,只对非空值执行操作;

    fun main() {
        val listWithNulls: List<String?> = listOf("abc", null)
        for (item in listWithNulls) {
            item?.let { println(it) } // 输出 abc 并忽略 null
        }
    }
    

    3)使用 Elvis (?:) 操作符,检查结果为空的时候的返回值;

    fun main() {   
        var b :String? = null
        val l = b?.length ?: -1
        println(l) // 输出 -1
    }
    

    如果?:左侧表达式非空,elvis 操作符就返回其左侧表达式,否则返回右侧表达式。 请注意,当且仅当左侧为空时,才会对右侧表达式求值。

    4)使用!!非空断言运算符,将任何值转换为非空类型,若该值为空则抛出 NPE;

    fun main() {   
        var a = "abc"
        var b :String? = null    
        println(a!!.length) // 输出3
        println(b!!.length) //抛出 NPE异常
    }
    

    如果 b 非空,就返回 b.length,否则抛出 NPE异常。

    5)使用as?操作符尝试转换成指定类型,如果尝试转换不成功则返回 null;

    fun main() {
        var a = "abc"   
        var b: Int ? = a as? Int
        println(b)  // 输出 null
    }
    

    6)使用filterNotNull操作符,过滤一个可空类型元素集合中的非空元素;

    fun main() {    
        val nullableList: List<Int?> = listOf(1, 2, null, 4)
        val intList: List<Int> = nullableList.filterNotNull()
        println(intList)  // 输出 [1, 2, 4]
    }
    
    3. 空的安全总结

    空安全设计的操作符及描述,如下表:

    操作符 描述
    ? 可空操作符,声明可空类型,避免抛出NPE;
    ?. 安全调用操作符,为空返回null,避免抛出NPE;
    ?.let{} ?.let一起使用,用于遍历集合时,则忽略null值,只对非空值执行操作;
    ?: Elvis操作符, val t = b?.length ?: -1,如果 ?: 左侧表达式(b?.length)非空,elvis 操作符就返回其左侧表达式,否则返回右侧表达式(-1);
    !! 非空断言运算符,将任何值转换为非空类型,若该值为空则抛出NPE;
    as? 尝试转换成指定类型,如果尝试转换不成功则返回null;
    filterNotNull 过滤一个可空类型元素集合中的非空元素。

    相关文章

      网友评论

          本文标题:Kotlin空类型安全处理总结

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