在Kotlin中,类型系统将可空类型和不可空类型进行了区分,例如,String为不可空类型,String?为可空类型,如果将不可空类型赋值为null将会编译不通过。
在Kotlin中,类型系统区分可以可空类型和不可空类型。例如,类型的常规变量String
不能为空:
var a: String = "abc"
a = null // compilation error
为了允许空值,我们可以声明一个变量为空字符串,写成String?
:
var b: String? = "abc"
b = null // ok
现在,如果您调用方法或访问某个属性a
,它肯定不会导致NPE,因此您可以放心地说:
val l = a.length
但是如果你想访问同一个属性b
,那就不安全了,编译器报告一个错误:
val l = b.length // error: variable 'b' can be null
但我们仍然需要访问该属性,对吧?有几种方法可以做到这一点。
1. 使用b?.length的形式调用,如果b为null,返回-1,否则返回b.length
val l = b?.length ?: -1
相当于:
val l: Int = if (b != null) b.length else -1
2. 使用b!!.length()的形式调用,如果b为null,抛出空指针异常,否则返回b.length
val l = b!!.length
ClassCastException
如果对象不是目标类型,则可能产生ClassCastException异常,例如:
var a: Long = 1
val aInt: Int? = a as Int // java.lang.ClassCastException
使用安全转换,如果尝试失败,则返回null:
val aInt: Int? = a as? Int
如果您有一个可为空类型的元素的集合并且想要过滤非空元素,则可以使用filterNotNull
以下方法来实现:
val nullableList: List<Int?> = listOf(1, 2, null, 4)
val intList: List<Int> = nullableList.filterNotNull()