一、空引用异常
许多编程语言(包括 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
}