【Kotlin】空值和空类型(?、!!、?.、?:)

Kotlin空值与空类型详解

在这里插入图片描述

所有的变量除了引用一个具体的值之外,还有一种特殊的值可以使用,那就是null,它代表空值,也就是不引用任何对象。

在 Java 中null是一个非常常见的值,因为在某些情况下,引用类型的变量默认值就是 null,这就经常会导致程序中出现一些空指针导致的异常;在 Kotlin 中,对空值处理是非常严格的,正常情况下,变量是不能直接赋值为null的,否则会报错,无法编译通过:

var str: String = null    // 编译错误

所有的类型默认为非空类型,非空类型的变量是不允许被赋值为 null 的,这直接在编译阶段就避免了其他语言中经常存在的空指针问题

如果希望某个变量在初始情况下使用null而不去引用某一个具体对象,此时需要将变量的类型修改为可空类型,只需在类型名称的后面添加一个?

var str: String? = null

既然现在是可空类型,那么很多问题就会出现,比如当一个变量为null时,此时如果使用类中的一些成员方法或是获取成员属性时,会出现一些问题:

var str: String? = null
println(str.length);      // 编译错误

这里由于操作的是一个空类型,它有可能值为null,可以想象一下,如果一个变量不引用任何对象,此时又让对象做一些事情(执行函数),而压根就没这个对象,这会导致上面所说的空指针异常

此时,为了安全,需要对变量进行判断,看看其是否不为null然后才能去做一些正常情况下该做的事情:

fun main() {
    var str: String? = null
  	// 这里直接通过if语句判断str变量是否为null,如果不是才执行
    if (str != null) {
        println(str.length)  // 现在就可以编译通过了
    }
}

只要能确保某个空类型变量的值不为空,那么就可以正常执行操作。实际上在 if 内部,因为已经判断不为 null 了,所以 str 被智能类型转换为非空类型

在有些情况下,我们可能已经非常清楚,这里的 str 一定不为 null,即使它是一个可空类型变量。我们可以告诉编译器,这里一定是安全的,只管执行就好:

fun main() {
    var str: String? = null
  	// 使用非空断言操作符!!.来明确不会出现null问题
    println(str!!.length)
}

虽然使用**非空断言操作符 !!**能够进行强制操作,实际上同样存在安全问题。也许存在没有考虑到的情况会导致这里为 null ,也说不定?对于一些我们拿不定具体会不会出现 null 的情况,有没有更好的解决办法?

Kotlin 提供了一种更安全的空类型操作,要安全地访问可能包含null值的对象的属性,请使用安全调用运算符?.,如果对象的属性为null则安全调用运算符返回null,像下面这样:

fun main() {
    var str: String? = null
    println(str?.length)      // 使用安全调用运算符 ?.
}

这里的调用结果存在两种情况:

  • 如果 str 为 null,那么这里得到的结果就是 null,并且不会正常执行后面的操作
  • 如果 str 不为 null,那就正常返回这里本应该得到的结果

因此,使用安全调用运算符后,如果遇到 null 的情况,那么不会正常进行原本的操作,而是直接返回null作为结果,这在有些时候非常好用,比如希望一个学生类型的变量在为null时就不执行对应的语句:

fun main() {
    val stu: Student? = null
    stu?.hello()
}

不过在有些时候,可能希望如果变量为 null,在使用安全调用运算符时,返回一个自定义的结果,而不是null,这时该怎么做呢?我们可以使用 Elvis 运算符 ?:

fun main() {
    val str: String? = null
  	// Elvis运算符 ?: 左侧为空值检测目标,右侧为检测到null时返回的结果
    val len: Int = str?.length ?: 0
}W

这里使用了 Elvis 运算符来判断左侧是否为 null,如果左侧为 null,那么这里直接得到右侧的自定义值,这个运算符长得像其他语言里面的三元运算符。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

shayudiandian

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值