lazy:延迟加载
1、 lazy提供了初始化的方法,不过真正初始化这个动作发生的时机却是在第一次被使用时。
2、 lazy()是一个函数, 可接受一个Lambda表达式作为参数,第一次调用将会执行 Lambda 表达式,以后调用该参数返回以前记住的结果.
3、 可以理解为lazy{…}函数的最后一行为返回值
4、 lazy只能实现对属性为val的初始化,对于var需要用lateinit
5、 lateinit的使用有很多限制的,比如只能在不可null的对象上使用,不能为primitives(Int、Float之类)等等
延迟初始化属性与变量
一般地,属性声明为非空类型必须在构造函数中初始化。 然而,这经常不方便。
例如:属性可以通过依赖注入来初始化, 或者在单元测试的 setup 方法中初始化。
这种情况下,你不能在构造函数内提供一个非空初始器。但你仍然想在类体中引用该属性时避免空检查。
为处理这种情况,你可以用 lateinit 修饰符标记该属性:
public class MyTest {
lateinit var subject: TestSubject
@SetUp fun setup() {
subject = TestSubject()
}
@Test fun test() {
subject.method() // 直接解引用
}
}
该修饰符只能用于在类体中的属性(不是在主构造函数中声明的 var 属性,并且仅当该属性没有自定义 getter 或 setter 时),而自 Kotlin 1.2 起,也用于顶层属性与局部变量。该属性或变量必须为非空类型,并且不能是原生类型。
在初始化前访问一个 lateinit 属性会抛出一个特定异常,该异常明确标识该属性被访问及它没有初始化的事实。
检测一个 lateinit var 是否已初始化(自 1.2 起)
要检测一个 lateinit var 是否已经初始化过,请在该属性的引用上使用 .isInitialized:
if (foo::bar.isInitialized) {
println(foo.bar)
}
此检测仅对可词法级访问的属性可用,即声明位于同一个类型内、位于其中一个外围类型中或者位于相同文件的顶层的属性。