由于kotlin有嚴(yán)格的語法要求變量需要聲明是否可以為null,但由于在實際的業(yè)務(wù)場景中,這個變量必須在某些時候才能做初始化操作,并且這個變量肯定不為null,如果為null,就是邏輯有問題了。這個時候可以使用lateinit來修飾這個變量。如果沒有初始化就使用這個變量,那么就會拋出異常。
在鐵鋒等地區(qū),都構(gòu)建了全面的區(qū)域性戰(zhàn)略布局,加強發(fā)展的系統(tǒng)性、市場前瞻性、產(chǎn)品創(chuàng)新能力,以專注、極致的服務(wù)理念,為客戶提供網(wǎng)站設(shè)計、網(wǎng)站建設(shè) 網(wǎng)站設(shè)計制作定制網(wǎng)站,公司網(wǎng)站建設(shè),企業(yè)網(wǎng)站建設(shè),品牌網(wǎng)站制作,全網(wǎng)營銷推廣,成都外貿(mào)網(wǎng)站建設(shè)公司,鐵鋒網(wǎng)站建設(shè)費用合理。class LateInitExample {
lateinit var value:String
}
fun main() {
val example = LateInitExample()
// 如果沒有賦值就使用,直接拋出異常。
example.value = "lateinit example"
println("${example.value}")
}
2.lateinit的具體實現(xiàn)public class LateInitExample {
private String value;
public String getValue() {
// 如果沒有初始化過,就拋出異常
if (value == null){
throw new RuntimeException("lateinit property value has not been initialized");
}
return value;
}
public void setValue(String value) {
// 這里要做非null檢查
this.value = value;
}
}
我們知道使用kotlin的屬性其實是在調(diào)用get和set方法,lateinit關(guān)鍵字其實就是對get和set方法做了一些操作。
注意lateinit不能修飾基本類型。
二、by lazyby 和 lazy要單獨拿出來看,不能當(dāng)做一個整體來看。
by:這里涉及到了kotlin的委托中委托屬性。
lazy:一個kotlin的函數(shù)
1.屬性委托簡單通俗理解就是這個變量的get,set都是委托給了另外一個類來去操作。
如果是var變量,必須要有g(shù)etValue和setValue2個方法,val變量不需要setValue方法。
// 委托的類
class Delegate {
operator fun getValue(thisRef: Any?, property: KProperty<*>): String {
return "$thisRef, 這里委托了 ${property.name} 屬性"
}
operator fun setValue(thisRef: Any?, property: KProperty<*>, value: String) {
println("$thisRef 的 ${property.name} 屬性賦值為 $value")
}
}
注意別和kotlin的get和set方法混淆了!!!!
語法是: val/var<屬性名>:<類型>by<表達(dá)式>
Kotlin 標(biāo)準(zhǔn)庫為幾種有用的委托提供了工廠方法,延遲屬性 Lazy就是其中之一。
https://www.runoob.com/kotlin/kotlin-delegated.html
2.lazy的實現(xiàn)public actual funlazy(lock: Any?, initializer: () ->T): Lazy= SynchronizedLazyImpl(initializer, lock)
private class SynchronizedLazyImpl(initializer: () ->T, lock: Any? = null) : Lazy, Serializable {
private var initializer: (() ->T)? = initializer
@Volatile private var _value: Any? = UNINITIALIZED_VALUE
// final field is required to enable safe publication of constructed instance
private val lock = lock ?: this
override val value: T
get() {
val _v1 = _value
if (_v1 !== UNINITIALIZED_VALUE) {
@Suppress("UNCHECKED_CAST")
return _v1 as T
}
return synchronized(lock) {
val _v2 = _value
if (_v2 !== UNINITIALIZED_VALUE) {
@Suppress("UNCHECKED_CAST") (_v2 as T)
} else {
val typedValue = initializer!!()
_value = typedValue
initializer = null
typedValue
}
}
}
override fun isInitialized(): Boolean = _value !== UNINITIALIZED_VALUE
override fun toString(): String = if (isInitialized()) value.toString() else "Lazy value not initialized yet."
private fun writeReplace(): Any = InitializedLazyImpl(value)
}
看到這里,相信大家只剩下一個疑惑了,為什么沒有g(shù)etValue方法,不是說by的實現(xiàn)需要getValue方法嗎?這里,kotlin使用了擴展函數(shù)來做。
// 這里返回value,就會執(zhí)行實現(xiàn)類的override value get了。
public inline operator funLazy.getValue(thisRef: Any?, property: KProperty<*>): T = value
三、總結(jié)從本質(zhì)上來說,lateinit和by lazy的區(qū)別是體現(xiàn)在內(nèi)存上:
lateinit修飾的屬性,會在內(nèi)存中創(chuàng)建,只不過沒有賦值
by lazy修飾的屬性,只有在使用的時候才會在內(nèi)存中創(chuàng)建
你是否還在尋找穩(wěn)定的海外服務(wù)器提供商?創(chuàng)新互聯(lián)www.cdcxhl.cn海外機房具備T級流量清洗系統(tǒng)配攻擊溯源,準(zhǔn)確流量調(diào)度確保服務(wù)器高可用性,企業(yè)級服務(wù)器適合批量采購,新人活動首月15元起,快前往官網(wǎng)查看詳情吧
網(wǎng)站標(biāo)題:Kotlin的lateinit和bylazy的區(qū)別-創(chuàng)新互聯(lián)
文章源于:http://jinyejixie.com/article38/dhdpsp.html
成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供網(wǎng)站營銷、電子商務(wù)、虛擬主機、品牌網(wǎng)站設(shè)計、建站公司、移動網(wǎng)站建設(shè)
聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請盡快告知,我們將會在第一時間刪除。文章觀點不代表本網(wǎng)站立場,如需處理請聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時需注明來源: 創(chuàng)新互聯(lián)
猜你還喜歡下面的內(nèi)容