Kotlin的lateinit和bylazy的区别-创新互联

一、lateinit 1.lateinit的使用

由于kotlin有严格的语法要求变量需要声明是否可以为null,但由于在实际的业务场景中,这个变量必须在某些时候才能做初始化操作,并且这个变量肯定不为null,如果为null,就是逻辑有问题了。这个时候可以使用lateinit来修饰这个变量。如果没有初始化就使用这个变量,那么就会抛出异常。

在铁锋等地区,都构建了全面的区域性战略布局,加强发展的系统性、市场前瞻性、产品创新能力,以专注、极致的服务理念,为客户提供网站设计、网站建设 网站设计制作定制网站,公司网站建设,企业网站建设,品牌网站制作,全网营销推广,成都外贸网站建设公司,铁锋网站建设费用合理。
class LateInitExample {
    lateinit var value:String
}

fun main() {
    val example = LateInitExample()
    // 如果没有赋值就使用,直接抛出异常。
    example.value = "lateinit example"
    println("${example.value}")
}
2.lateinit的具体实现
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的属性其实是在调用get和set方法,lateinit关键字其实就是对get和set方法做了一些操作。

注意lateinit不能修饰基本类型。

二、by lazy

by 和 lazy要单独拿出来看,不能当做一个整体来看。

by:这里涉及到了kotlin的委托中委托属性。

lazy:一个kotlin的函数

1.属性委托

简单通俗理解就是这个变量的get,set都是委托给了另外一个类来去操作。

如果是var变量,必须要有getValue和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<表达式>

Kotlin 标准库为几种有用的委托提供了工厂方法,延迟属性 Lazy就是其中之一。

https://www.runoob.com/kotlin/kotlin-delegated.html

2.lazy的实现
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)
}

看到这里,相信大家只剩下一个疑惑了,为什么没有getValue方法,不是说by的实现需要getValue方法吗?这里,kotlin使用了扩展函数来做。

// 这里返回value,就会执行实现类的override value get了。
public inline operator funLazy.getValue(thisRef: Any?, property: KProperty<*>): T = value
三、总结

从本质上来说,lateinit和by lazy的区别是体现在内存上:

lateinit修饰的属性,会在内存中创建,只不过没有赋值

by lazy修饰的属性,只有在使用的时候才会在内存中创建

你是否还在寻找稳定的海外服务器提供商?创新互联www.cdcxhl.cn海外机房具备T级流量清洗系统配攻击溯源,准确流量调度确保服务器高可用性,企业级服务器适合批量采购,新人活动首月15元起,快前往官网查看详情吧

网站标题:Kotlin的lateinit和bylazy的区别-创新互联
文章源于:https://www.cdcxhl.com/article38/dhdpsp.html

成都网站建设公司_创新互联,为您提供网站营销电子商务虚拟主机品牌网站设计建站公司移动网站建设

广告

声明:本网站发布的内容(图片、视频和文字)以用户投稿、用户转载内容为主,如果涉及侵权请尽快告知,我们将会在第一时间删除。文章观点不代表本网站立场,如需处理请联系客服。电话:028-86922220;邮箱:631063699@qq.com。内容未经允许不得转载,或转载时需注明来源: 创新互联

h5响应式网站建设