Android之Kotlin:Kotlin之 lateinit 和 by lazy

image.png

最近在用kotlin写项目的时候,发现在初始化的时候用到了lateinit和by
lazy两种方式,好奇他们有什么区别,就来写一下文章,加深下理解。

一、lateinit(延迟初始化属性)

一般地,属性声明为非空类型必须在构造函数中初始化(我们知道,kotlin中默认是空安全的,任何属性的声明都必须有初始化值,如果支持可空”?”,才能把属性声明为null)。然而这样经常不方便,例如:属性可以通过依赖注入来初始化,或者单元测试的setup方法中初始化,这种情况下,你不能在构造函数内提供一个非空初始器,但你仍然想在类体中引用该属性时避免空检查。为处理这种情况,我们可以使用lateinit

val nameA:String //报红线 提示如下 
Property must be initialized or be abstract
lateinit var name:String //lateinit可以避免这种情况

该修饰只能用于类体中(不是在主构造函数中)声明的var属性,注意是var(可变属性)并且仅当该属性没有自定义getter或setter时,该属性必须是非空类型,并且不能是原生类型。

在初始化前访问一个lateinit属性会抛出一个特定异常,该异常明确标识该属性被访问及它没有初始化的事实。

by lazy(惰性初始化)

惰性初始化是一种常见的模式,直到第一次访问该属性的时候,才根据需要创建对象的一部分,当初始化过程消耗大量资源并且在使用对象时并不总是需要数据时,这个非常有用。

val nameB: String by lazy {
    println("getLazy")
    "123"
}

println(nameB)
println(nameB)

输入结果:
getLazy
123
123

首先需要注意的是:

by lazy只能作用于val关键字标注的属性。
当属性用到的时候才会初始化”lazy{}”里面的内容
而且再次调用属性的时候,只会得到结果,而不会再次执行lazy{}的运行过程
总结:以上可以看出两个都是用来初始化属性的,但是有点互补的意思。可以根据不同情况选择使用。

推荐阅读更多精彩内容