Kotlin lateinit和by lazy的区别
一、简要说明
Koltin中属性在声明的同时也要求要被初始化,否则会报错。
但是有些应用场景,不想在声明的时候就初始化,那么可以使用lateinit.
延时初始化属性就是不必在类实例化时初始化它,可以根据需要在程序运行期初始化,而没有lateinit声明的非可空类型属性必须在类实例化时初始化。
其实就是让编译期在检查时不要因为属性变量未被初始化而报错。
PS:
- 延时初始化属性要求:
- 不能是可空类型;
- 只能使用为var声明;
- lateinit关键字应该放在var之前。
二、实际使用对比
简单的代码示例对比:
未使用lateinit情况
|
|
|
|
|
|
调试结果:
使用lateinit
|
|
|
|
|
|
调用结果:
三、对比
by lazy,Kotlin中提供一种委托属性,使用by关键字声明。
惰性加载属性和延迟初始化属性类似,只有第一次访问该属性时才进行初始化
不同的是惰性加载属性使用lazy函数声明委托属性,而延迟初始化属性lateinit关键字修饰属性。
惰性加载属性必须是val的,而延迟初始化属性必须是var的。
lazy 应用于单例模式的时候(if-null-then-init-else-return),而且当且仅当变量被第一次调用的时候,委托方法才会执行。
四、区别?怎么用?
如果是值可修改的变量(即在之后的使用中可能被重新赋值),使用lateInit模式
如果变量的初始化取决于外部对象(例如需要一些外部变量参与初始化),使用lateInit模式。这种情况下,lazy模式也可行但并不直接适用。
如果变量仅仅初始化一次并且全局共享,且更多的是内部使用(依赖于类内部的变量),请使用lazy模式。从实现的角度来看,lateinit模式仍然可用,但lazy模式更有利于封装你的初始化代码。
综上所述,不考虑对变量值是否可变的控制,lateinit模式是lazy模式的超集,你可以在任何使用lazy模式的地方用lateinit模式替代,反之则不然。但在可能的情况下,请尽量使用lazy模式,因为lateinit模式在函数中暴露了太多的逻辑代码,使得代码更加混乱,相比而言,lazy模式更好地封装了细节,且更安全。
总结而言,对于变量的初始化,优先选择lazy模式,其次再考虑late模式……实在不行,选择最原始的方法手动实现。