Kotlin中为什么对类可变属性做非空判断后无法智能转换?
Kotlin 智能转换差异原因
核心原因是两段代码中w的变量类型不同,Kotlin 智能转换(Smart Cast)对不同变量的适用规则不同:
- 第二段代码中
w是函数内的局部可变变量:
局部变量的作用域仅限定在当前函数内部,不存在外部代码跨作用域修改该变量的可能,编译器可以完全确定if(w!=null)判断执行后,w的值不会被其他逻辑、其他线程修改,因此可以安全执行智能转换,将可空的String?自动转为非空的String类型,可以直接调用length属性。 - 第一段代码中
w是类的可变成员属性:
类的成员属性属于类实例的全局可访问属性,只要权限允许,类内部其他方法、其他线程持有类实例都可以随时修改w的值。编译器无法保证在if(w!=null)判断完成后,到执行println(w.length)的间隙,w会不会被其他逻辑修改为null,因此禁止智能转换,抛出你看到的报错。
第一段代码的修复方案
你可以选择以下任意一种方案修复编译问题:
- 使用安全调用符,自动判断非空再执行后续逻辑:
println(w?.length)
- 使用
let作用域函数捕获w的当前值:
w?.let { println(it.length) }
- 将
w改为不可变属性val,属性初始化后无法修改,编译器允许智能转换:
val w: String? = "Hello"
内容的提问来源于stack exchange,提问作者DevRS
相关产品推荐
相关产品推荐

