美文网首页
Kotlin与Java:空安全

Kotlin与Java:空安全

作者: 程序引力 | 来源:发表于2018-12-16 23:29 被阅读7次

    前言

    空指针异常(NPE)是最为普遍与常见的异常,同时它也会引起诸如程序崩溃等非常严重的后果。为了避免出现NPE,常常需要开发者对变量进行判空处理。特别是在Android中常常会使用‘链式’调用,但为了避免NPE,需要‘步步’判空,使得程序代码啰嗦且难以维护。为解决此问题,Kotlin提供了新的声明,用于保证空安全。

    空安全

    空安全简单来说可在两个阶段进行:

    • 声明时保证空安全
    • 使用时保证空安全

    任何一个环节保证了空安全,则可避免空指针异常。

    声明时保证空安全

    • Java
      在Java中并不支持在声明变量时就保证空安全,即不支持在编译时就判断变量是否可能为空。

    • Kotlin
      Kotlin提供了新的方式,用于声明变量是否可能为空。声明的语法为:

    变量名:变量类型?
    

    添加?的变量类型表示其对象可能为空。若不添加表示其对象不可能为空,在编译时就可以提前发现该问题。

    var a: String = "abc"
    a = null // 编译错误
    
    var b: String? = "abc"
    b = null // ok
    

    在这一例子中,变量a没有声明为可空类型,若对其赋值为空,则会编译报错。但对于变量b声明为可空类型后,可以令其为空。

    使用时保证空安全

    • Java
      在java中无法再声明时就保证空安全,为此要避免NPE,必须在使用变量时保证空安全。最基本也是最常见的手段就是:
    if (b != null){
        //xxx
    }
    
    • Kotlin
      在Kotlin中如果某个变量声明为可空的类型,则在使用时也需要注意是否为空。Kotlin同样支持像Java那样显式判空。同时也提供了安全调用符,即 ?.
    val a = "Kotlin"
    val b: String? = null
    println(b?.length)
    println(a?.length)
    

    如果b不为空,就返回b.length,若b为空,就返回null。该表达式的返回值类型为Int?

    更为常见地,该调用符也可以支持’链式‘调用:

    bob?.department?.head?.name
    

    若其中任何一个环节为空,则返回空。

    安全调用也可以出现在赋值的左侧。这样,如果调用链中的任何一个接收者为空都会跳过赋值,而右侧的表达式根本不会求值:

    person?.department?.head = managersPool.getManager()
    

    空处理

    • Java
      当我们有一个可空的引用 b 时,我们可以说“如果 b 非空,我使用它;否则使用某个非空的值 x”:
    if (b != null){
        return b.length;
    } else {
        return -1;
    }
    
    • Kotlin
      要实现在变量为空时的处理,Kotlin不仅支持像Java那样的显式赋值,还拥有更为简单的操作符,即Elvis 操作符 ?:
    val l = b?.length ?: -1
    

    如果 ?: 左侧表达式非空,elvis 操作符就返回其左侧表达式,否则返回右侧表达式。 请注意,当且仅当左侧为空时,才会对右侧表达式求值。

    额外操作符

    • Kotlin
      在Kotlin中还支持一些Java不支持的新的操作符,如!!操作符。
    val l = b!!.length
    

    如果该调用不为空,则返回预期值,若为空,则抛出空指针异常。

    安全类型转换:如果对象不是目标类型,那么常规类型转换可能会导致 ClassCastException。 另一个选择是使用安全的类型转换,如果尝试转换不成功则返回 null:

    val aInt: Int? = a as? Int
    

    相关文章

      网友评论

          本文标题:Kotlin与Java:空安全

          本文链接:https://www.haomeiwen.com/subject/kayfkqtx.html