美文网首页
Kotlin的延迟初始化: lateinit var和by la

Kotlin的延迟初始化: lateinit var和by la

作者: 奔跑的蛙牛 | 来源:发表于2019-03-16 11:05 被阅读0次

Koltin中属性在声明的同时也要求要被初始化,否则会报错。 例如以下代码:

private var name0: String //报错
private var name1: String = "xiaoming" //不报错
private var name2: String? = null //不报错

可是有的时候,我并不想声明一个类型可空的对象,而且我也没办法在对象一声明的时候就为它初始化,那么这时就需要用到Kotlin提供的延迟初始化。Kotlin中有两种延迟初始化的方式。一种是lateinit var,一种是by lazy。

lateinit var

private lateinit var name: String
  1. lateinit var只能用来修饰类属性,不能用来修饰局部变量,并且只能用来修饰对象,不能用来修饰基本类型(因为基本类型的属性在类加载后的准备阶段都会被初始化为默认值)。
  2. lateinit var的作用也比较简单,就是让编译期在检查时不要因为属性变量未被初始化而报错。
  3. Kotlin相信当开发者显式使用lateinit var 关键字的时候,他一定也会在后面某个合理的时机将该属性对象初始化的(然而,谁知道呢,也许他用完才想起还没初始化)。

下面来看一下 by lazy

by lazy本身是一种属性委托。属性委托的关键字是by。by lazy 的写法如下:

//用于属性延迟初始化
val name: Int by lazy { 1 }

//用于局部变量延迟初始化
public fun foo() {
    val bar by lazy { "hello" }
    println(bar)
}

by lazy具体是怎么实现的:生成一个该属性的附加属性:nameXXdelegate
在构造器中,将使用lazy(()->T)创建的Lazy实例对象赋值给nameXXdelegate;
当该属性被调用,即其getter方法被调用时返回nameXXdelegate.getVaule(),而nameXXdelegate.getVaule()方法的返回结果是对象nameXXdelegate内部的_value属性值,在getVaule()第一次被调用时会将_value进行初始化,往后都是直接将_value的值返回,从而实现属性值的唯一一次初始化。

lateinit var和by lazy使用区别?
  首先两者的应用场景是略有不同的。
  然后,虽然两者都可以推迟属性初始化的时间,但是lateinit var只是让编译期忽略对属性未初始化的检查,后续在哪里以及何时初始化还需要开发者自己决定。
  而by lazy真正做到了声明的同时也指定了延迟初始化时的行为,在属性被第一次被使用的时候能自动初始化。但这些功能是要为此付出一丢丢代价的。

相关文章

网友评论

      本文标题:Kotlin的延迟初始化: lateinit var和by la

      本文链接:https://www.haomeiwen.com/subject/tumjmqtx.html