Kotlin 空值处理

Kotlin 类型转换,在程序开发过程中,经常会遇到空指针异常的问题,如果对这个问题处理不当,还可能会引起程序的崩溃(crash),因此在Kotlin中,为了避免出现空指针异常的问题,引入了Null机制,本章就来详细讲解一下Kotlin程序中的Null机制。

可空类型变量(?)

Kotlin把变量分成两种类型,一种是可空类型的变量,一种是非空类型的变量。一般情况下,一个变量默认是非空类型。当某个变量的值可以为空时,必须在声明处的数据类型后添加“?”来标识该引用可为空。具体示例如下:

var name: String   //声明非空变量 
var age: Int?      //声明可空变量

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

在使用可空变量时,如果不知道该变量的初始值,则需要将其赋值为null,否则会报“variable 'age' must be initialized”异常。接下来我们通过一段代码来学习如何判断变量是否为空,以及如何使用可空变量,具体代码如下所示。

package com.itheima.chapter02.variable
fun main(args: Array<String>) {
    var name: String = "Tom"        // 非空变量
    var telephone: String? = null   // 可空变量
    if (telephone != null) {
        print(telephone.length)
    } else {
        telephone = "18800008888"
        print("telephone =" + telephone)
   }
}

运行结果:

telephone=18800008888

上述代码中,定义了一个非空变量name,一个可空变量telephone。在使用可空变量时,常规的方式就是对可空变量进行判断,如果telephone不为空则输出电话号码的长度,否则将telephone赋值为18800008888并输出。

安全调用符(?.)

上面我们讲解了可空变量在使用时需要通过if…else语句进行判断,然后再进行相应的操作。这样的使用方式还是比较复杂,为此Kotlin提供了一个安全调用符“?.”,专门用于调用可空类型变量中的成员方法或属性,其语法格式为“变量?.成员”。其作用是判断变量是否为null,如果不为null才调用变量的成员方法或者属性。接下来我们通过一段代码进行演示,具体代码如下所示。

package com.itheima.chapter02.variable
fun main(args: Array<String>) {
    var name: String = "Tom"
    var telephone: String? = null
    var result = telephone?.length
    println(result)
}

运行结果:

null

从运行结果可以看出,在使用“?.”调用可空变量的属性时,如果当前变量为空,则程序编译也不会报错,而是返回一个null值。

Elvis操作符(?:)

在使用安全调用符调用可空变量中的成员方法或属性时,如果当前变量为空,则会返回一个null值,但有时即使当前变量为null,也不想返回一个null值而是指定一个默认值,此时该如何处理呢?为了解决这样的问题,Kotlin中提供了一个Elvis操作符(?:),通过Elvis操作符(?:)可以指定可空变量为null时,调用该变量中的成员方法或属性的返回值,其语法格式为“表达式?:表达式”。如果左侧表达式非空,则返回左侧表达式的值,否则返回右侧表达式的值。当且仅当左侧为空时,才会对右侧表达式求值。接下来我们通过一段代码进行演示,具体代码如下所示。

package com.itheima.chapter02.variable
fun main(args: Array<String>) {
    var name: String = "Tom"
    var telephone: String? = null
    var result = telephone?.length ?: "18800008888"
    println(result)
}

运行结果:

18800008888

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

非空断言(!!.)

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

package com.itheima.chapter02.variable
fun main(args: Array<String>) {
    var telephone: String? = null    // 声明可空类型变量
    var result = telephone!!.length  // 使用非空断言
    println(result)
}

运行结果:

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

从运行结果可以看出,程序抛出了空指针异常,如果变量telephone赋值不为空,则程序可以正常运行。
安全调用符与非空断言运算符都可以调用可空变量的方法,但是在使用时有一定的差别,如表所示。

操作符 安全 推荐
安全调用符(?.) 当变量值为null时,不会抛出异常,更安全 推荐使用
非空断言(!!) 当变量值为null时,会抛出异常,不安全 可空类型变量经过非空断言后,这个变量变为非空变量,非空变量为null时,不能调用该变量中的成员方法或属性,不推荐

酷客教程相关文章:

赞(0)

评论 抢沙发

评论前必须登录!