日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問(wèn) 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) > 编程资源 > 编程问答 >内容正文

编程问答

Kotlin实战指南九:延迟初始化

發(fā)布時(shí)間:2024/9/30 编程问答 33 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Kotlin实战指南九:延迟初始化 小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

轉(zhuǎn)載請(qǐng)標(biāo)明出處:https://blog.csdn.net/zhaoyanjun6/article/details/93764289
本文出自【趙彥軍的博客】


高階函數(shù)

    • lateinit 延遲初始化
    • lazy 延遲初始化
    • lazy 延遲模式
    • 總結(jié)

Koltin中屬性在聲明的同時(shí)也要求要被初始化,否則會(huì)報(bào)錯(cuò)。例如以下代碼:

private var name0: String //報(bào)錯(cuò) private var name1: String = "xiaoming" //不報(bào)錯(cuò) private var name2: String? = null //不報(bào)錯(cuò)

可是有的時(shí)候,我并不想聲明一個(gè)類型可空的對(duì)象,而且我也沒(méi)辦法在對(duì)象一聲明的時(shí)候就為它初始化,那么這時(shí)就需要用到Kotlin提供的延遲初始化。Kotlin中有兩種延遲初始化的方式。一種是 lateinit var,一種是by lazy。

lateinit 延遲初始化

private lateinit var name: String
  • lateinit var只能用來(lái)修飾類屬性,不能用來(lái)修飾局部變量,并且只能用來(lái)修飾對(duì)象,不能用來(lái)修飾基本類型(因?yàn)榛绢愋偷膶傩栽陬惣虞d后的準(zhǔn)備階段都會(huì)被初始化為默認(rèn)值)。
  • lateinit var的作用也比較簡(jiǎn)單,就是讓編譯期在檢查時(shí)不要因?yàn)閷傩宰兞课幢怀跏蓟鴪?bào)錯(cuò)。
  • Kotlin相信當(dāng)開(kāi)發(fā)者顯式使用lateinit var關(guān)鍵字的時(shí)候,他一定也會(huì)在后面某個(gè)合理的時(shí)機(jī)將該屬性對(duì)象初始化的.

lateinit在Android中使用

class MainActivity : AppCompatActivity() {private lateinit var bt: Buttonoverride fun onCreate(savedInstanceState: Bundle?) {super.onCreate(savedInstanceState)setContentView(R.layout.activity_main)bt = findViewById(R.id.bt)bt.setOnClickListener {Toast.makeText(baseContext, "click", Toast.LENGTH_SHORT).show()}} }

lazy 延遲初始化

by lazy本身是一種屬性委托。屬性委托的關(guān)鍵字是by。by lazy的寫(xiě)法如下:

//用于屬性延遲初始化 val name: Int by lazy { 1 }//用于局部變量延遲初始化 public fun foo() {val bar by lazy { "hello" }println(bar) }
  • by lazy要求屬性聲明為val,即不可變變量,在java中相當(dāng)于被final修飾。這意味著該變量一旦初始化后就不允許再被修改值了(基本類型是值不能被修改,對(duì)象類型是引用不能被修改)。{}內(nèi)的操作就是返回唯一一次初始化的結(jié)果。
  • by lazy可以使用于類屬性或者局部變量。

在 Android 中使用

class MainActivity : AppCompatActivity() {private val bt by lazy {findViewById<Button>(R.id.bt)}override fun onCreate(savedInstanceState: Bundle?) {super.onCreate(savedInstanceState)setContentView(R.layout.activity_main)bt.setOnClickListener {Toast.makeText(baseContext, "click", Toast.LENGTH_SHORT).show()}} }

lazy 延遲模式

在使用 lazy 延遲初始化的時(shí)候,Kotlin提供了3中模式,源碼如下:

public actual fun <T> lazy(mode: LazyThreadSafetyMode, initializer: () -> T): Lazy<T> =when (mode) {LazyThreadSafetyMode.SYNCHRONIZED -> SynchronizedLazyImpl(initializer)LazyThreadSafetyMode.PUBLICATION -> SafePublicationLazyImpl(initializer)LazyThreadSafetyMode.NONE -> UnsafeLazyImpl(initializer)}
  • 模式1: LazyThreadSafetyMode.SYNCHRONIZED
    線程安全模式,Initializer函數(shù)只能被調(diào)用一次,返回的對(duì)象只有一個(gè)

  • 模式2:LazyThreadSafetyMode.PUBLICATION
    在對(duì)未初始化的[Lazy]實(shí)例值進(jìn)行并發(fā)訪問(wèn)時(shí),可以多次調(diào)用Initializer函數(shù),但只有第一個(gè)返回值將用作[Lazy]實(shí)例的值。

  • 模式3:LazyThreadSafetyMode.NONE
    沒(méi)有鎖用于同步對(duì)[Lazy]實(shí)例值的訪問(wèn); 如果從多個(gè)線程訪問(wèn)實(shí)例,可能會(huì)有多個(gè)實(shí)例。除非保證[Lazy]實(shí)例永遠(yuǎn)不會(huì)從多個(gè)線程初始化,否則不應(yīng)使用此模式。

當(dāng)我們模式都不用的情況下,默認(rèn)使用 LazyThreadSafetyMode.SYNCHRONIZED 線程安全模式。源碼如下:

public actual fun <T> lazy(initializer: () -> T): Lazy<T> = SynchronizedLazyImpl(initializer)

幾個(gè)例子,使用延遲模式創(chuàng)建一個(gè)單例

class Manager {init {Log.e("zhaoyanjun:inin", "初始化")}companion object {val instance by lazy(LazyThreadSafetyMode.SYNCHRONIZED) {Manager()}} }

總結(jié)

那么,再總結(jié)一下,lateinit var和by lazy哪個(gè)更好用?
首先兩者的應(yīng)用場(chǎng)景是略有不同的。然后,雖然兩者都可以推遲屬性初始化的時(shí)間,但是lateinit var只是讓編譯期忽略對(duì)屬性未初始化的檢查,后續(xù)在哪里以及何時(shí)初始化還需要開(kāi)發(fā)者自己決定。

而by lazy真正做到了聲明的同時(shí)也指定了延遲初始化時(shí)的行為,在屬性被第一次被使用的時(shí)候能自動(dòng)初始化。但這些功能是要為此付出一丟丟代價(jià)的。


個(gè)人微信號(hào):zhaoyanjun125 , 歡迎關(guān)注

總結(jié)

以上是生活随笔為你收集整理的Kotlin实战指南九:延迟初始化的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。

如果覺(jué)得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。