Kotlin中的lateinit和lazy关键字如何理解

lateinit

假设你要声明一个变量,刚开始不会对其进行赋值,一段时间之后才对他赋值。
你可能会这么写:

var a:String //这么写会报错
//进化一下 
var a:Stirng?=null

后一种写法虽然不会报错,但是好像a变量可以为空了,我们并不想看到这种情况。
lateinit 这时候就派上用场了,这代表你告诉编辑器,我先声明这么一个变量并且之后会对其进行初始化。
注意:由于之后会对其进行修改,所以lateinit只能用var修饰,不能用val修饰!

所以变为如下方式声明:

lateinit var a:String

注意三点:
1.类型为var类型
2. 必须制定类型,否则导致This property must either have a type annotation, be initialized or be delegated
3. 一般用在函数体或者类中

如果在未赋值的时候就调用该变量,会导致uninitializedPropertyAccessException: lateinit property a has not been initialized

lazy

假设你要初始化A对象,但是A对象中有一个HeavyClass(也就是说这个类的初始化会消耗很多资源),所以会导致A的初始化很慢,而且你也不一定会用到这个HeavyClass对象,用lazy修饰这个对象,就可以保证用到该对象时候再进行初始化。
原来代码:

class A{
    private val heavyClass : HeavyClass = HeavyClass()

    fun doSomething(){
        println("hello")
    }
}

class HeavyClass{
    constructor(){
        println("爷被创建了...")
    }
}

用lazy进行优化:

class A {
    private val heavyClass by lazy {
        HeavyClass()
    }
    fun doSomething(){
        println("hello")
    }
}

class HeavyClass{
    constructor(){
        println("爷被创建了...")
    }
}

注意几点:
1.HeavyClass只有在被需要的时候,才会创建
2.HeavyClass创建之后,同一个A对象,下次访问的时候,还是这个HeavyClass,但是创建一个新的A对象的话,就会创建新的HeavyClass
验证代码:

class A {
    constructor(){
        println("A被创建了...")
    }
    private val heavyClass by lazy {
        HeavyClass()
    }
    fun doSomething(){
        println(heavyClass)
    }
}
class HeavyClass{
    constructor(){
        println("爷被创建了...")
    }
}
fun main() {
    val a=A()
    a.doSomething()
    a.doSomething()
    val b=A()
    b.doSomething()
}

最终输出:

A被创建了...
爷被创建了...
HeavyClass@7440e464
HeavyClass@7440e464
A被创建了...
爷被创建了...
HeavyClass@49476842

有帮助的话,点赞加关注吧~

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值