奇怪的Kotlin空安全行为

时间:2018-11-28 11:42:41

标签: kotlin

如果将全局属性定义为private var raceLoadJob: Job? = null,那么Kotlin会要求您在方法中执行类似的操作

if (raceLoadJob != null){
    if (raceLoadJob!!.isActive) return // null assertation
}

Kotlin将要求断言,因为raceLoadJob值可以更改。我首先想到的是多线程。

因此您可以将代码更改为

raceLoadJob?.let {
    if (it.isActive) return
}

但是,如果您对这部分代码进行反编译,则会看到

Job var10000 = this.raceLoadJob;
if (this.raceLoadJob != null) {
   Job var1 = var10000;
   if (var1.isActive()) {
      return;
   }
}

您可以看到,该条件是this.raceLoadJob != null,而不是var10000 != null。这意味着从理论上讲,由于分配了raceLoadJob值,该代码可能会失败,但是var10000是null

这是问题还是我的推理错误?

1 个答案:

答案 0 :(得分:5)

推理中的错误是您正在通过查看反编译器输出而不是字节码来分析Kotlin代码的行为。 Kotlin编译器会生成javac不使用的字节码模式,因此反编译器(旨在对javac输出进行反编译)只能提供实际逻辑的近似表示。

如果您查看实际的字节码,它看起来像这样:

ALOAD 0
GETFIELD raceLoadJob : LRaceLoadJob;
DUP
IFNULL L1
ASTORE 2

它表明所检查的null值与后续计算中使用的值完全相同。