繁体   English   中英

Kotlin:如果没有阻止,则空检查

[英]Kotlin: Null check in if block

我最近开始学习Kotlin。 我无法理解的一件事是空检查块。 以下语句被认为是不安全的,并且编译器不允许您对其进行编译。

    var testVar: String? = null;

    // if (testVar != null )
    {
        // Doing some work....
        println(testVar.length)
    }

但是,当您取消注释if行时,一切正常。 这看起来很棒。

但是,如果 // Doing some work....是计算昂贵,而另一个线程的值更改testVarnull ,而这个线程在// Doing some work线? 在这种情况下:

  • 程序是否抛出NullPointerException?
  • 要么:
  • 字节码是否缓存testVar的值并在if块内使用缓存的值?

在最初的示例中, var是函数的局部变量吗? 例如:

fun doStuff() {
    var testVar: String? = null

    if (testVar != null) {
        println(testVar.length)
    }
}

在这种情况下,没有其他作用域引用过testVar因此没有别的更改。 但是,如果var是类属性,即

class MyClass {
    var testVar: String? = null

    fun doStuff() {
        if (testVar != null) {
            println(testVar.length)
        }
    }
}

这将无法编译,因为在检查和使用之间,另一个线程可能已将testVar设置为null。

更进一步,如果您尝试技巧:

fun doStuff() {
    var testVar: String? = null

    fun trickyFunction() {
        testVar = null
    }

    if (testVar != null) {
        trickyFunction()
        println(testVar.length)
    }
}

由于变量被更改的闭包捕获,因此编译器将失败。 因此,通常来说,如果您能够通过智能广播将变量使用为非空值,则不必担心NPE的任何潜力。

对于第二种情况(var属性),最好依靠.let来捕获对当前值的不可变引用,即

testVar?.let { capturedTestVar ->
    println(capturedTestVar.length)
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM