【譯】kotlin中l(wèi)ateinit和by lazy的區(qū)別

原文內(nèi)容來自 Kotlin - Property initialization using “by lazy” vs. “l(fā)ateinit”

lazy { ... } delegate can only be used for val properties, whereas lateinit can only be applied to vars, because it can't be compiled to a final field, thus no immutability can be guaranteed;

  • lazy { ... }只能被用在被val修飾的變量上,而lateinit只能被用var修飾的變量上剥险,因?yàn)楸?code>lateinit修飾的字段無法被編譯為一個final字段、因此無法保證它的不可變性基显。

lateinit var has a backing field which stores the value, and by lazy { ... } creates a delegate object in which the value is stored once calculated, stores the reference to the delegate instance in the class object and generates the getter for the property that works with the delegate instance. So if you need the backing field present in the class, use lateinit

  • lateinit修飾的變量有一個幕后字段用來存儲它的值椭员,而by lazy { ... }創(chuàng)建了一個包含by lazy { ... }中代碼返回值的實(shí)例對象雨涛,實(shí)例對象持有這個值并生成一個可以在實(shí)例對象中調(diào)用的這個值的getter。所以如果你需要在代碼中使用幕后字段的話赶么,使用lateinit

In addition to vals, lateinit cannot be used for nullable properties and Java primitive types (this is because of null used for uninitialized value)

  • 除了被val修飾的變量外肩豁,lateinit也不能被用來修飾可空的屬性和java的基本類型(因?yàn)閷τ诳煽疹愋停瑫心J(rèn)值null

lateinit var can be initialized from anywhere the object is seen from, e.g. from inside a framework code, and multiple initialization scenarios are possible for different objects of a single class. by lazy { ... }, in turn, defines the only initializer for the property, which can be altered only by overriding the property in a subclass. If you want your property to be initialized from outside in a way probably unknown beforehand, use lateinit

  • lateinit修飾的變量可以在對象(代碼)的任何地方進(jìn)行初始化辫呻,而且同一個類的不同對象可以對這個變量進(jìn)行多次的初始化(賦值)清钥。但是,對于by lazy { ... }修飾的變量,只擁有唯一一個聲明在{}中的初始化構(gòu)造器放闺,如果你想要修改它祟昭,你只能通過在子類中覆寫的方式來修改它的值。所以怖侦,如果你想要你的屬性在其他地方以不是你事先定義好的值初始化的話篡悟,使用lateinit

Initialization by lazy { ... } is thread-safe by default and guarantees that the initializer is invoked at most once (but this can be altered by using another lazy overload). In case of lateinit var, it's up to the user's code to initialize the property correctly in multi-threaded environments.

  • by lazy { ... }的初始化默認(rèn)是線程安全的,并且能保證by lazy { ... }代碼塊中的代碼最多被調(diào)用一次匾寝。而lateinit var默認(rèn)是不保證線程安全的搬葬,它的情況完全取決于使用者的代碼。

A Lazy instance can be saved, passed around and even used for multiple properties. On contrary, lateinit vars do not store any additional runtime state (only null in the field for uninitialized value).

  • Lazy實(shí)例是有值的艳悔,這個值可以被存儲急凰、傳遞和使用。但是很钓,被lateinit var修飾的變量不存儲任何多余的運(yùn)行時(shí)狀態(tài)香府,只有值還未被初始化的null值。

If you hold a reference to an instance of Lazy, isInitialized() allows you to check whether it has already been initialized (and you can obtain such instance with reflection from a delegated property). To check whether a lateinit property has been initialized, you can use property::isInitialized since Kotlin 1.2.

  • 如果你持有一個Lazy實(shí)例的引用码倦,你可以使用它的isInitialized()方法來判斷它是否已經(jīng)被初始化。從Kotlin1.2開始锭碳,你也可以使用方法引用的方式來獲取這個值袁稽。

A lambda passed to by lazy { ... } may capture references from the context where it is used into its closure.. It will then store the references and release them only once the property has been initialized. This may lead to object hierarchies, such as Android activities, not being released for too long (or ever, if the property remains accessible and is never accessed), so you should be careful about what you use inside the initializer lambda.

  • by lazy { ... }中傳遞的lambda表達(dá)式可能會捕獲它的閉包中使用的上下文的引用,引用會一直被持有直到變量被初始化擒抛。因此這樣可能會導(dǎo)致內(nèi)存泄漏推汽,所以仔細(xì)考慮你在lambda表達(dá)式中使用的值是否合理
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市歧沪,隨后出現(xiàn)的幾起案子歹撒,更是在濱河造成了極大的恐慌,老刑警劉巖诊胞,帶你破解...
    沈念sama閱讀 218,941評論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件暖夭,死亡現(xiàn)場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)迈着,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,397評論 3 395
  • 文/潘曉璐 我一進(jìn)店門竭望,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人裕菠,你說我怎么就攤上這事咬清。” “怎么了奴潘?”我有些...
    開封第一講書人閱讀 165,345評論 0 356
  • 文/不壞的土叔 我叫張陵旧烧,是天一觀的道長。 經(jīng)常有香客問我画髓,道長粪滤,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,851評論 1 295
  • 正文 為了忘掉前任雀扶,我火速辦了婚禮杖小,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘愚墓。我一直安慰自己予权,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,868評論 6 392
  • 文/花漫 我一把揭開白布浪册。 她就那樣靜靜地躺著扫腺,像睡著了一般。 火紅的嫁衣襯著肌膚如雪村象。 梳的紋絲不亂的頭發(fā)上笆环,一...
    開封第一講書人閱讀 51,688評論 1 305
  • 那天,我揣著相機(jī)與錄音厚者,去河邊找鬼躁劣。 笑死,一個胖子當(dāng)著我的面吹牛库菲,可吹牛的內(nèi)容都是我干的账忘。 我是一名探鬼主播,決...
    沈念sama閱讀 40,414評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼熙宇,長吁一口氣:“原來是場噩夢啊……” “哼鳖擒!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起烫止,我...
    開封第一講書人閱讀 39,319評論 0 276
  • 序言:老撾萬榮一對情侶失蹤蒋荚,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后馆蠕,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體期升,經(jīng)...
    沈念sama閱讀 45,775評論 1 315
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡惊奇,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,945評論 3 336
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了吓妆。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片赊时。...
    茶點(diǎn)故事閱讀 40,096評論 1 350
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖行拢,靈堂內(nèi)的尸體忽然破棺而出祖秒,到底是詐尸還是另有隱情,我是刑警寧澤舟奠,帶...
    沈念sama閱讀 35,789評論 5 346
  • 正文 年R本政府宣布竭缝,位于F島的核電站,受9級特大地震影響沼瘫,放射性物質(zhì)發(fā)生泄漏抬纸。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,437評論 3 331
  • 文/蒙蒙 一耿戚、第九天 我趴在偏房一處隱蔽的房頂上張望湿故。 院中可真熱鬧,春花似錦膜蛔、人聲如沸坛猪。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,993評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽墅茉。三九已至,卻和暖如春呜呐,著一層夾襖步出監(jiān)牢的瞬間就斤,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,107評論 1 271
  • 我被黑心中介騙來泰國打工蘑辑, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留洋机,地道東北人。 一個月前我還...
    沈念sama閱讀 48,308評論 3 372
  • 正文 我出身青樓以躯,卻偏偏與公主長得像槐秧,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子忧设,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,037評論 2 355

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