编译器抱怨,因为理论上,不同的线程可能会在赋值语句和返回语句之间更改someVar
。
这里的惯用解决方案是使用property delegation:
private val someVar: SomeClass by lazy { getDefaultSomeVar() }
这初始化时,它在一个线程安全的方式是第一次访问属性。还要注意,它现在是一个不可空的val,而不是一个可为空的var,这使得它通常更容易处理。
您确实失去了稍后修改它的能力。如果它需要变化,你现在必须自己做。示例实现看到这个SO问题:Kotlin lazy default property
以下两种解决方案采取方法的问题(即“Java的方式”)是理所当然的,只是显示方式,以防止编译器警告。然而,在你的情况下,这些是而不是建议,因为他们都有懒惰初始化属性的缺点:
1)引入一个局部变量。这个变量是安全,不会被其他线程正在发生突变,并允许编译器做一个聪明的演员:
private fun getSomeVar(): SomeClass {
var value = someVar
if(value == null) {
value = getDefaultSomeVar()
someVar = value
}
return value
}
的方法本身仍不过不是线程安全的。在多线程环境中,可以多次调用getDefaultSomeVar()
,并且不保证此方法的返回值等于someVar
。
2)使用!!
:double bang操作符。这将可空类型转换为不可空。但是现在你失去了kotlin编译器对你执行的保护和null safety。
return someVar!!
由于文档所说的那样:“如果你想要一个NPE,你可以把它”
有什么警告?首选项在哪里? –