注册

浅谈Kotlin编程-Kotlin空值处理

前言


许多编程语⾔(包括 Java)中最常⻅的错误之⼀,就是访问空成员会导致空异常(NullPointerException 或简称 NPE)。


开发中,经常会遇到空指针异常,如果对这个问题处理不当,还会引起程序的崩溃(crash),在Kotlin中,为了避免出现空指针异常,引入了 Null机制,本篇就来了解一下Kotlin中的 Null机制


本文总览


Kotlin空值处理.png


1. 可空类型变量(?)


Kotlin中把变量分成了两种类型



  • 可空类型变量
  • 非空类型变量

通常,一个变量默认是非空类型。若要变量的值可以为空,必须在声明处的数据类型后添加 ? 来标识该变量可为空。如下示例:


var phone: String   //声明非空变量 
var price: Int? //声明可空变量

上述代码中,phone 为非空变量,price 为可空变量。若给变量name赋值为null,编译器会提示“Null can not be a value of a non-null type String”错误信息。引起这个错误的原因是Kotlin官方约定变量默认为非空类型时,该变量不能赋值为null, 而price 赋值为null,编译可以通过。


声明可空变量时,若不知道初始值,则需将其赋值为null,否则会报“variable price must be initialized”异常信息。


通过一段示例代码来学习如何判断变量是否为空,以及如何使用可空变量:


fun main() {
var name: String = "Any" // 非空变量
var phone: String? = null // 可空变量
if (phone != null) {
print(phone.length)
} else {
phone = "12345678901"
print("phone = " + phone)
}
}

运行结果:


phone = 12345678901

上述代码,定义一个非空变量 name,一个可空变量 phone。这段示例代码对可空变量进行判断,如果 phone 不为空则输出 phone的长度,否则将phone赋值为12345678901并打印输出。


2. 安全调用符(?.)


上一点的示例中,可空变量在使用时需要先通过if…else判断,然后再进行相应的操作,这样使用还是比较繁琐。Kotlin提供了一个安全调用符?.,用于调用可空类型变量中的成员方法或属性,语法格式为“变量?.成员”。其作用是先判断变量是否为null,如果不为null才调用变量的成员方法或者属性。


fun main() {
var name: String = "Any"
var phone: String? = null
var result = phone?.length
println(result)
}

运行结果:


null

结果可以看出,在使用?.调用可空变量的属性时,若当前变量为空,则程序编译正常运行,且返回一个null值。


3. Elvis操作符(?:)


安全调用符调用可空变量中的成员方法或属性时,如果当前变量为空,则返回一个null值,但有时不想返回一个null值而是指定一个默认值,该如何处理呢?Kotlin中提供了一个Elvis操作符(?:),通过Elvis操作符(?:)可以指定可空变量为null时,调用该变量中的成员方法或属性的返回值,其语法格式为 表达式 ?: 表达式 。若左边表达式非空,则返回左边表达式的值,否则返回右边表达式的值。


fun main() {
var name: String = "Any"
var phone: String? = null
var result = phone?.length ?: "12345678901"
println(result)
}

运行结果:


12345678901

从结果可以看出,当变量phone为空时,使用?:操作符会返回指定的默认值“12345678901”,而非null值。


4. 非空断言(!!.)


除了使用安全调用符(?.)来使用可空类型的变量之外,还可以通过非空断言(!!.)来调用可空类型变量的成员方法或属性。使用非空断言时,调用变量成员方法或属性的语法结构为 “变量!!.成员” 。非空断言(!!.)会将任何变量(可空类型变量或者非空类型变量)转换为非空类型的变量,若该变量为空则抛出异常。接下来我们通过一个例子来演示非空断言(!!.)的使用,具体代码如下所示。


fun main() {
var phone: String? = null // 声明可空类型变量
var result = phone!!.length // 使用非空断言
println(result)
}

运行结果:


Exception in thread"main"kotlin.KotlinNullPointerException
at NoEmptyAssertionKt.main
(NoEmptyAssertion.kt:4)

运行结果抛出了空指针异常,若变量phone赋值不为空,则程序可以正常运行。

安全调用符与非空断言运算符都可以调用可空变量的方法,但是在使用时有一定的差别,如表所示。






















操作符安全是否推荐
安全调用符(?.)当变量值为null时,不会抛出异常,更安全推荐使用
非空断言(!!)当变量值为null时,会抛出异常,不安全可空类型变量经过非空断言后,这个变量变为非空变量,非空变量为null时,会报异常,不推荐

总结


上面四种情况的介绍,可以说的很全面地囊括 kotlin 中的空处理情况,开发中应根据实际场景使用合适的操作符。


作者:南巷羽
链接:https://juejin.cn/post/7134636916514750495
来源:稀土掘金
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

0 个评论

要回复文章请先登录注册