編譯器抱怨,因爲理論上,不同的線程可能會在賦值語句和返回語句之間更改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,你可以把它」
有什麼警告?首選項在哪裏? –