You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Kotlin空安全:为何用?.而非if判空?还有哪些优势?

Kotlin空安全:安全调用操作符?. vs 空判断if语句

在学习Kotlin空安全时,有理论提到:Kotlin有针对NPE的有效解决方案。

先看一段会触发NPE的代码(代码1):

class Foo {
    val c: String          // Non-nullable

    init {
        bar()
        c = ""             // Initialised for the first time here
    }

    fun bar() {
        println(c.length)  // Oh dear
    }
}

fun main(args: Array<String>) {
    Foo()
}

这段代码的问题在于init块中先调用了bar(),此时非空属性c尚未完成初始化,因此执行println(c.length)时会抛出空指针异常。

为避免这类空指针问题,Kotlin提供了?.安全调用操作符,示例代码(代码2)如下:

val c: String? = null

fun bar() {
    print(c?.length)
}

当然,我们也可以用传统的if语句做空判断:

fun bar() {
    if(c != null){
        print(c.length)
    }
}

问题解答

1. 既然可以使用if语句进行空判断,为何要采用?.的写法?

?.的优势远不止简洁,核心价值体现在这些场景:

  • 链式调用更流畅:如果是多层嵌套的可空对象(比如user?.address?.city?.name),用?.可以一行完成安全调用;换成if判断则需要多层嵌套,代码会变得冗余且难以阅读。
  • 自动处理空值分支:?.在遇到空值时直接返回null,无需手动编写else分支。比如需要获取可空长度时,val len = c?.length直接就能得到Int?类型的值,而if判断需要额外处理空值场景的返回逻辑。
  • 与其他空安全特性无缝结合:可以和Elvis操作符?:搭配快速设置默认值,比如val len = c?.length ?: 0,一行代码就能完成“空值时返回0”的逻辑,if判断要实现同样效果需要更多代码。
  • 规避智能转换的局限性:在lambda、跨函数调用等复杂作用域中,Kotlin的智能转换可能无法识别if判断后的非空性,此时?.能确保调用始终安全,而if判断可能会触发编译错误。

2. 仅仅是因为代码更简洁吗,还是存在其他未留意到的优势?

当然不只是简洁。除了上面提到的几点,?.的写法更贴合Kotlin的空安全设计理念,代码意图更清晰——一眼就能识别这是针对可空对象的安全操作,而if判断的空检查很容易和业务逻辑的条件判断混在一起,增加代码的理解成本。此外,?.在编译层面的处理更高效,编译器能针对安全调用做特定优化,而if判断的空检查则是通用的条件分支处理。

内容的提问来源于stack exchange,提问作者Ash Kecthum

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.11 00:46:29