简介
Kotlin 的类型系统旨在从我们的代码中消除 NullPointerException。减少线上NullException 异常的发生。使我们的程序更加的稳定和健壮。
可空类型与非空类型
Kotlin 中区分可空类型与非空类型。那么系统当中又是怎么区分这两种类型的呢?如下:
- String 类型的常规变量不能容纳 null:
private fun method(){
var result:String = "abc"
result = null
}
当赋值result=null 的时候编译器报错 提示 Null can not be a value of a non-null type String
- 变量为可空类型
?
private fun method(){
var result:String? = "abc"
result = null
Log.i("wly",result)
}
编译不在报错执行输出 null
。加上?
之后一个 Kotlin 变量就像 Java 变量一样没有非空的限制。
安全调用 ?.
private fun method(){
var result:String? = "abc"
Log.i("wly","length =${result.length}")
}
当我们变量使用可空 ?
操作符之后,由此引发另一个问题就是空引用导致出现空指针异常,IDE 编译器报错 Only safe (?.) or non-null asserted (!!.) calls are allowed on a nullable receiver of type String?
修正:
private fun method(){
var result:String? = "abc"
Log.i("wly","length =${result?.length}")
}
该代码会对变量做一次非空确认之后再调用方法,这是 Kotlin 的写法,并且它可以做到线程安全。
!! 操作符
private fun method(){
var result:String? = "abc"
Log.i("wly","length =${result!!.length}")
}
非空断言运算符(!!)将任何值转换为非空类型,若该值为空则抛出异常。实际上和 Java 就没什么两样了,从而也就享受不到 Kotlin 的空安全设计带来的好处啦。示例代码如果 result==null
将会出现NullException 异常。
安全的类型转换
如果对象不是目标类型,那么常规类型转换可能会导致 ClassCastException。 另一个选择是使用安全的类型转换,如果尝试转换不成功则返回 null:
private fun method(){
var result:String? = "abc"
val test: Int? = result as? Int
}
可空类型的集合过滤 .filterNotNull()
可空类型元素的集合,并且想要过滤非空元素,你可以使用 filterNotNull 来实现
private fun listMethod(){
val nullableList: List<Int?> = listOf(1, 2, null, 4)
val intList: List<Int> = nullableList.filterNotNull()
Log.i("wly","intList = $intList")
}
参考
Kotlin 中文网 https://www.kotlincn.net/docs/reference/null-safety.html