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
- lateinit var只能用来修饰类属性,不能用来修饰局部变量,并且只能用来修饰对象,不能用来修饰基本类型(因为基本类型的属性在类加载后的准备阶段都会被初始化为默认值)。
- lateinit var的作用也比较简单,就是让编译期在检查时不要因为属性变量未被初始化而报错。
- 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真正做到了声明的同时也指定了延迟初始化时的行为,在属性被第一次被使用的时候能自动初始化。
网友评论