为何Kotlin中分开定义可空变量会改变编译器行为?
Kotlin编译器对两段可空变量代码的行为差异解释
先看你提供的两段代码:
第一段代码:
// first piece of code start var name1: String? name1 = null println(name1!!.length) // Unresolved reference: length // first piece of code end
第二段代码:
// second piece of code start var name2: String? = null println(name2!!.length) // second piece of code end
核心原因是编译器智能类型分析的处理差异
第一段代码的红色提示是工具静态分析的偏差:
name1是先声明后赋值的变量,虽然你紧接着把它设为null,但IntelliJ的代码检查器此时没有正确识别!!非空断言的效果——它仍然把name1!!当成了String?类型,而可空类型没有直接的length属性,所以误报“Unresolved reference: length”。实际上这段代码是可以通过编译的,运行时会和第二段一样抛出NullPointerException,属于编辑器检查的小bug,不是Kotlin语言规则的问题。第二段代码符合Kotlin的断言规则:
name2是声明时直接初始化的变量,编译器明确知道它的值是null,但!!操作符的作用就是强制告知编译器“我确认这个变量非空,跳过空安全检查”。编译器会信任你的断言,将name2!!判定为非空String类型,因此length是合法引用,不会出现编译错误。运行时因为实际值是null,触发!!的预期行为——抛出NPE。
内容的提问来源于stack exchange,提问作者iwsnmw
相关产品推荐
相关产品推荐

