初識 Kotlin (二) ---- lateinit vs lazy

Kotlin Property Initialization

在使用 kotlin開發中,因爲各種原因,我們會經常需要使用到延遲加載的功能(不在構造函數中初始化屬性),目前kotlin的延遲加載主要有兩種:lateinitlazy

lateinit

    // 聲明一個string變量
    lateinit var a1: String
    
    private fun test() {
        // 初始化
        a1 = "test1"
    }

var 之前添加 lateinit,然後選擇你想要的時候,初始化,但是有以下需要注意的地方:

  • lateinit 只能修飾變量 var,不能修飾常量 val
  • lateinit 不能對可空類型使用
  • lateinit 不能對 java 基本類型使用,例如:DoubleIntLong
  • 在調用 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="執行到我時,纔會進行控件初始化"

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