Kotlin 變量, 使用 Lazy 還是 Late?

今天我們介紹 Kotlin 中的兩個新特性:

  • lazy initialization(懶初始化),即:推遲一個變量的初始化時機(jī)。這是個十分方便的特性于购,因為我們通常會遇到這樣的情況涯曲,一個變量直到使用時才需要被初始化
    語法:Initialization by Lazy(懶初始化)
    例如:val myUtil by lazy { MyUtil(parameter1, parameter2)}
    上面這段代碼創(chuàng)建了一個MyUtil類型的對象芽卿。MyUtil類型的對象只創(chuàng)建一次,就是第一次使用myUtil的時候.
  • Late Initialization(延遲初始化)
    語法:lateinit var myUtil: MyUtil
    設(shè)置好延遲初始化后在以后的某個函數(shù)中
    myUtil = MyUtil(parameter1, parameter2)進(jìn)行初始化

大致來說就是將初始化與定義變量分離開來。

為什么有兩種方式抑淫?使用場景如何绷落?

盡管兩種方式有著相同的理念,本質(zhì)上卻有著很大的差異始苇。簡單地看下變量的類型砌烁,一個是 val(值不可變),另一個是 var(值可變)埂蕊。這已經(jīng)很能說明問題了往弓。下面是一些典型的使用場景單例變量
有時疏唾,我們需要的只是變量的單個實(shí)例,全局共享這個變量

MyUtil getMyUtil() {
    if (myUtil == null) myUtil = new MyUtil(param1, param2);
    return myUtil;
}

這在單例模式中是非常常見的函似,我們可以確保所有地方訪問的都是同一個實(shí)例槐脏。同時也能保證這個對象只在我們需要時被創(chuàng)建。在這種情況下撇寞,Lazy Initialization(懶初始化模式) 將很有用顿天。

初始化一個不可為空的變量

在 Kotlin 中,我們需要預(yù)先定義好一個變量是否可為空蔑担。這使得編譯器能在編譯時識別出潛在的 null 對象牌废,以避免 NPE (空指針異常)。

因此啤握,對于一個不可為空的成員變量鸟缕,當(dāng)類被創(chuàng)建時,它必須要被賦予一個非空的值排抬。如果在類被創(chuàng)建時懂从,初始化這個成員變量的所有依賴對象都已經(jīng)準(zhǔn)備好,那當(dāng)然就不是問題了蹲蒲。不幸的是番甩,有些情況下,這些依賴對象(例如上述例子中的 param1 和 param2)需要等到相關(guān)依賴對象都準(zhǔn)備好了才能給它初始化届搁。

基于這種情況缘薛,lateinit(延遲初始化模式) 給我們帶來了便利,Kotlin 以優(yōu)雅的方式允許一個成員變量在定義時是未初始化的卡睦,之后當(dāng)一切準(zhǔn)備就緒了再執(zhí)行它的初始化宴胧。。

使用依賴注入的變量

如果你在 Kotlin 中使用了依賴注入框架(例如 Dagger2
)么翰,那些預(yù)先聲明的變量也無法成功初始化牺汤。在這種情況下,必須使用 lateinit關(guān)鍵字確保變量在稍后將被初始化浩嫌。

@Inject 
lateinit var myUtil: MyUtil

實(shí)際上檐迟,lateinit關(guān)鍵字就是因為這個原因而在 Kotlin 中明確地引入的。

何時用码耐?用哪個追迟?

上述例子僅是一小部分使用情境。事實(shí)上只要是不可為空的變量骚腥,很多情況下都是適用的敦间。有一些簡單的規(guī)則來幫助你決定該用哪一個模式:

  • 如果是值可修改的變量(即在之后的使用中可能被重新賦值),使用lateInit模式
  • 如果變量的初始化取決于外部對象(例如需要一些外部變量參與初始化),使用 lateInit模式廓块。這種情況下厢绝,lazy模式也可行但并不直接適用。
  • 如果變量僅僅初始化一次并且全局共享带猴,且更多的是內(nèi)部使用(依賴于類內(nèi)部的變量)昔汉,請使用 lazy模式。從實(shí)現(xiàn)的角度來看lateinit模式仍然可用拴清,但 lazy模式更有利于封裝你的初始化代碼靶病。

綜上所述,不考慮對變量值是否可變的控制口予,lateinit 模式是 lazy模式的超集(不是繼承關(guān)系,而是lateinit便利程度大于lazy)娄周,你可以在任何使用 lazy 模式的地方用 lateinit 模式替代,反之則不然沪停。但在可能的情況下煤辨,請盡量使用 lazy 模式,因為 lateinit 模式在函數(shù)中暴露了太多的邏輯代碼牙甫,使得代碼更加混亂掷酗,相比而言,lazy 模式更好地封裝了細(xì)節(jié)窟哺,且更安全。
總結(jié)而言技肩,對于變量的初始化且轨,優(yōu)先選擇 lazy模式,其次再考慮 lateinit 模式……實(shí)在不行虚婿,選擇最原始的方法手動實(shí)現(xiàn).

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末旋奢,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子然痊,更是在濱河造成了極大的恐慌至朗,老刑警劉巖,帶你破解...
    沈念sama閱讀 206,378評論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件剧浸,死亡現(xiàn)場離奇詭異锹引,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)唆香,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,356評論 2 382
  • 文/潘曉璐 我一進(jìn)店門嫌变,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人躬它,你說我怎么就攤上這事腾啥。” “怎么了?”我有些...
    開封第一講書人閱讀 152,702評論 0 342
  • 文/不壞的土叔 我叫張陵倘待,是天一觀的道長疮跑。 經(jīng)常有香客問我,道長凸舵,這世上最難降的妖魔是什么祸挪? 我笑而不...
    開封第一講書人閱讀 55,259評論 1 279
  • 正文 為了忘掉前任,我火速辦了婚禮贞间,結(jié)果婚禮上贿条,老公的妹妹穿的比我還像新娘。我一直安慰自己增热,他們只是感情好整以,可當(dāng)我...
    茶點(diǎn)故事閱讀 64,263評論 5 371
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著峻仇,像睡著了一般公黑。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上摄咆,一...
    開封第一講書人閱讀 49,036評論 1 285
  • 那天凡蚜,我揣著相機(jī)與錄音,去河邊找鬼吭从。 笑死朝蜘,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的涩金。 我是一名探鬼主播谱醇,決...
    沈念sama閱讀 38,349評論 3 400
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼步做!你這毒婦竟也來了副渴?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 36,979評論 0 259
  • 序言:老撾萬榮一對情侶失蹤全度,失蹤者是張志新(化名)和其女友劉穎煮剧,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體将鸵,經(jīng)...
    沈念sama閱讀 43,469評論 1 300
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡勉盅,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 35,938評論 2 323
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了咨堤。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片菇篡。...
    茶點(diǎn)故事閱讀 38,059評論 1 333
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖一喘,靈堂內(nèi)的尸體忽然破棺而出驱还,到底是詐尸還是另有隱情嗜暴,我是刑警寧澤,帶...
    沈念sama閱讀 33,703評論 4 323
  • 正文 年R本政府宣布议蟆,位于F島的核電站闷沥,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏咐容。R本人自食惡果不足惜舆逃,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,257評論 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望戳粒。 院中可真熱鬧路狮,春花似錦、人聲如沸蔚约。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,262評論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽苹祟。三九已至砸抛,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間树枫,已是汗流浹背直焙。 一陣腳步聲響...
    開封第一講書人閱讀 31,485評論 1 262
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留砂轻,地道東北人奔誓。 一個月前我還...
    沈念sama閱讀 45,501評論 2 354
  • 正文 我出身青樓,卻偏偏與公主長得像舔清,于是被迫代替她去往敵國和親丝里。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 42,792評論 2 345

推薦閱讀更多精彩內(nèi)容