请阐述Kotlin语言中安全调用运算符 ?. 与非空断言运算符 !! 在空安全处理上的差异,包括各自的使用场景和潜在风险。
考察说明
考查对Kotlin空安全机制中两种常用运算符的理解及其适用场景。
回答思路
- 【回答框架 1】安全调用 ?. 是Kotlin空安全的核心特性,当接收者不为null时才执行后续调用,否则整个表达式返回null,避免空指针异常。它常用于链式调用或属性访问,例如 val length = str?.length,若str为null则length为null,不会抛出异常。非空断言 !! 则明确断言接收者非null,若实际为null会立即抛出KotlinNullPointerException,相当于主动放弃空安全检查。
- 【回答框架 2】使用场景上,?. 适用于不确定对象是否为空且希望安全处理的场景,配合Elvis运算符 ?: 可提供默认值,如 val len = str?.length ?: 0。!! 适用于开发者能保证对象非null的情况,比如从某些框架获取的值、经过逻辑判断后非null的变量,但使用需谨慎,因为一旦断言失败会崩溃。
- 【回答框架 3】风险方面,过度使用 !! 会破坏空安全优势,使代码重新面临NPE风险;而滥用 ?. 可能导致空值在业务逻辑中静默传递,引发隐性bug。推荐优先使用 ?. 、?: 和 let 等安全调用,尽量将!!限制在明确非空且边界明确的区域,并配合注释说明。
- 【关键点 1】安全调用 ?. 在接收者为null时返回null,不抛异常;非空断言 !! 在接收者为null时抛出KotlinNullPointerException。
- 【关键点 2】?. 适用于不确定空值的场景,常与Elvis运算符配合提供默认值;!! 用于开发者确信非null的场景,但需承担NPE风险。
- 【关键点 3】过度使用 !! 会削弱空安全保护,而滥用 ?. 可能掩盖空值问题,应优先使用更安全的替代方案。
- 【易错点 1】误以为 ?. 能完全避免空安全问题,但若链式调用中后续调用也返回null,可能产生逻辑错误。
- 【易错点 2】在!!断言失败时未处理异常,导致应用崩溃,而错误地使用?.返回null可能导致后续逻辑异常。