Kotlin空安全

100 阅读2分钟

一、空引用异常

许多编程语言(包括 Java)中最常见的陷阱之一,就是访问空引用的成员会导致空引用异常。在 Java 中,这等同于 NullPointerException 或简称 NPE

二、 Kotlin出现NPE的场景

  • 显式调用 throw NullPointerException()

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

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

    • 传递一个在构造函数中出现的未初始化的 this 并用于其他地方(“泄漏 this”)。
    • 超类的构造函数调用一个开放成员,该成员在派生中类的实现使用了未初始化的状态。
  • Java 互操作:

    • 企图访问平台类型的 null 引用的成员;
    • 用于 Java 互操作的泛型类型的可空性问题,例如一段 Java 代码可能会向 Kotlin 的 MutableList<String> 中加入 null,就需要一个 MutableList<String?> 才能处理。
    • 由外部 Java 代码引发的其他问题。

三、可空引用与非空引用

在 Kotlin 中,类型系统区分一个引用可以容纳 null (可空引用)还是不能容纳(非空引用)

package com.haoran.s1
fun main(array: Array<String>){
    var a:String = "hello"     //非可空引用
//    a = null                 //编译时报错
    var b:String ? = "xiaoli"  //可空引用
    b = null
}

四、访问可空类型的几种补救措施

<1> 安全调用操作符 ?. 

<2> !! 无论是否为null 都要执行,同Java

<3> 条件检查 null,同Java

package com.haoran.s1


fun main(array: Array<String>){
    var a:String = "hello"     //非可空引用
//    a = null                 //编译时报错
    var b:String ? = "xiaoli"  //可空引用
    b = null
    //第一种补救措施如果真的是null后面就不执行,就不会引发空指针异常
    println(b?.length)
    println(a?.length) //a 是非可空引用 不需要使用空安全操作
    //第二种补救措施,无论是否是null都要执行(同Java)
    println(b!!.length)
    //第三种补救措施 (同Java)
    if (b!=null) b.length

}