Kotlin之 lateinit 和 by lazy(延遲初始化)

 

 

Kotlin之 lateinit 和 by lazy(延遲初始化)

 

 

一,lateinit(延遲初始化屬性)(只能用在var變量上)


一般地,屬性聲明爲非空類型必須在構造函數中初始化(我們知道,kotlin中默認是空安全的,任何屬性的聲明都必須有初始化值,如果支持可空”?”,才能把屬性聲明爲null)。然而這樣經常不方便,例如:屬性可以通過依賴注入來初始化,或者單元測試的setup方法中初始化,這種情況下,你不能在構造函數內提供一個非空初始器,但你仍然想在類體中引用該屬性時避免空檢查。爲處理這種情況,我們可以使用lateinit

val nameA:String //報紅線 提示如下 
Property must be initialized or be abstract

lateinit var name:String    //lateinit可以避免這種情況



該修飾只能用於類體中(不是在主構造函數中)聲明的var屬性,注意是var(可變屬性)並且僅當該屬性沒有自定義getter或setter時,該屬性必須是非空類型,並且不能是原生類型。

在初始化前訪問一個lateinit屬性會拋出一個特定異常,該異常明確標識該屬性被訪問及它沒有初始化的事實。

 

by lazy(惰性初始化)(只能用在val變量上)


惰性初始化是一種常見的模式,直到第一次訪問該屬性的時候,才根據需要創建對象的一部分,當初始化過程消耗大量資源並且在使用對象時並不總是需要數據時,這個非常有用。

val nameB: String by lazy {
    println("getLazy")
    "123"
}

println(nameB)
println(nameB)



輸入結果: 
getLazy 
123 
123

首先需要注意的是:

by lazy只能作用於val關鍵字標註的屬性。
當屬性用到的時候纔會初始化”lazy{}”裏面的內容
而且再次調用屬性的時候,只會得到結果,而不會再次執行lazy{}的運行過程
總結:以上可以看出兩個都是用來初始化屬性的,但是有點互補的意思。可以根據不同情況選擇使用。

 

備註:如果你想要線程安全,使用 blockingLazy(): 它還是按照同樣的方式工作,但保證了它的值只會在一個線程中計算,並且所有的線程都獲取的同一個值。

 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章