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

Kotlin安全调用?.执行逻辑疑问:为何test?.getname().isNullOrEmpty()返回Boolean

Kotlin安全调用与isNullOrEmpty()的疑问解答

问题背景

根据Kotlin官方文档中关于安全调用的说明:若调用链中任意属性为null,整个链返回null。原本的理解是,对于A?.B?.C,如果A为null,执行A?.时就会返回null并终止后续B?.C的执行。

但当?.与isNullOrEmpty()结合时,出现了和预期不符的情况:

  • 当test为null时,预期if(test?.getname().isNullOrEmpty())会抛出需要Boolean类型的异常
  • 另外,isNullOrEmpty()不能直接调用在null上,它需要Array<*>?这类对象
  • 但实际代码会打印“isNullOrEmpty() is executed”

同时,如下代码无法编译(提示Unresolved reference),因为isNullOrEmpty()不能直接在null上调用:

if(test?.isNullOrEmpty()) {
    println("isNullOrEmpty() can be ran on null")         
} else {
    //TODO
}

问题解答

1. Kotlin安全调用?.的执行逻辑

安全调用?.的核心规则很明确:如果调用者不为null,就执行后续的属性或方法调用;如果调用者是null,整个?.表达式直接返回null,并且不会执行后续紧跟的属性/方法调用。

这里容易混淆的是优先级:?.的优先级高于普通的.调用。比如test?.getname().isNullOrEmpty()会被Kotlin解析为(test?.getname()).isNullOrEmpty(),而不是把它当成连续的安全调用链。

2. 为何test?.getname().isNullOrEmpty()能返回Boolean类型?

问题的核心在于isNullOrEmpty()的实际接收者和Kotlin的扩展函数设计:

  • 当test为null时,test?.getname()的结果是null,这个null的类型是String?(假设getname()返回String)
  • Kotlin为CharSequence?(String实现了该接口)提供了可空类型的扩展函数isNullOrEmpty(),它的逻辑是:接收者为null时直接返回true;非null时调用非空的isEmpty()方法。
  • 你尝试的test?.isNullOrEmpty()编译失败,是因为test本身的类型并不是Array<*>?、CharSequence?这类拥有isNullOrEmpty()扩展函数的可空类型,所以编译器找不到对应的方法,报Unresolved reference。

内容的提问来源于stack exchange,提问作者Chloe L

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.23 09:22:35