奇怪的Kotlin零安全行为

Ufk*_*oku 3 kotlin

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

if (raceLoadJob != null){
    if (raceLoadJob!!.isActive) return // null assertation
}
Run Code Online (Sandbox Code Playgroud)

Kotlin会要求断言,因为raceLoadJob值可以更改.我想到的第一件事是多线程.

所以你可以改变代码

raceLoadJob?.let {
    if (it.isActive) return
}
Run Code Online (Sandbox Code Playgroud)

但是,如果您反编译这部分代码,您将会看到

Job var10000 = this.raceLoadJob;
if (this.raceLoadJob != null) {
   Job var1 = var10000;
   if (var1.isActive()) {
      return;
   }
}
Run Code Online (Sandbox Code Playgroud)

你可以看到,这种情况是this.raceLoadJob != null,但不是var10000 != null.这意味着理论上这个代码可能因为raceLoadJob赋值而失败,但var10000是null.

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

yol*_*ole 5

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

如果你看一下实际的字节码,它看起来像这样:

ALOAD 0
GETFIELD raceLoadJob : LRaceLoadJob;
DUP
IFNULL L1
ASTORE 2
Run Code Online (Sandbox Code Playgroud)

它显示检查null的值与后续计算中使用的值完全相同.