Kotlin Property Initialization
在使用 kotlin開發中,因爲各種原因,我們會經常需要使用到延遲加載的功能(不在構造函數中初始化屬性),目前kotlin的延遲加載主要有兩種:lateinit
和 lazy
lateinit
// 聲明一個string變量
lateinit var a1: String
private fun test() {
// 初始化
a1 = "test1"
}
在 var
之前添加 lateinit
,然後選擇你想要的時候,初始化,但是有以下需要注意的地方:
lateinit
只能修飾變量var
,不能修飾常量val
lateinit
不能對可空類型使用lateinit
不能對java
基本類型使用,例如:Double
、Int
、Long
等- 在調用
lateinit
修飾的變量時,如果變量還沒有初始化,則會拋出未初始化異常,報錯
lateinit
eg: 生命週期流程中進行獲取或者初始化的變量,比如 Android 的 onCreate()
class App : Application() {
init {
instance = this
}
companion object {
lateinit var instance: App
}
}
lazy
lazy
也是 kotlin
中常用的一種延遲加載方式,使用方法如下:
public class Example{
val name: String by lazy { “Amit Shekhar” }
}
使用時,在類型後面加 by lazy{}
即可,{}
中的最後一行代碼,需要返回初始化的結果,上述代碼中,"sss"
即爲最後初始化的值。下面是 lazy
的一些注意點:
lazy
只能對常量val
使用,不能修飾變量var
lazy
的加載時機爲第一次調用常量的時候,且只會加載一次(畢竟是個常量,只能賦值一次)
lazy 應用於單例模式(if-null-then-init-else-return),而且當且僅當變量被第一次調用的時候,委託方法纔會執行
lazy()
是接受一個 lambda
並返回一個 Lazy <T>
實例的函數,返回的實例可以作爲實現延遲屬性的委託: 第一次調用 get()
會執行已傳遞給 lazy()
的 lambda
表達式並記錄結果, 後續調用 get()
只是返回記錄的結果
val lazyValue: String by lazy {
println("computed!")
"Hello"
}
fun main(args: Array<String>) {
println(lazyValue)
println(lazyValue)
}
打印結果
computed!
Hello
Hello
比如這樣的常見操作,只獲取,不賦值,並且多次使用的對象
private val mUserMannager: UserMannager by lazy {
UserMannager.getInstance()
}
再比如 acitivity
中控件初始化的操作,一般傳統的進入界面就初始化所有的控件,而使用懶加載,只有用到時纔會對控件初始化
//kotlin 封裝:
fun <V : View> Activity.bindView(id: Int): Lazy<V> = lazy {
viewFinder(id) as V
}
//acitivity中擴展調用
private val Activity.viewFinder: Activity.(Int) -> View?
get() = { findViewById(it) }
//在activity中的使用姿勢
val mTextView by bindView<TextView>(R.id.text_view)
mTextView.text="執行到我時,纔會進行控件初始化"