持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第27天,[点击查看活动详情]
Kotlin中的Lazy和Lateinit属性
Kotlin语言中提供了许多对于我们开发者来说很好的功能,我们可以使用这些特性快速的构建一个高质量的应用程序,在所有的这些特性中,lateinit和lazy是很重要的初始化属性。你知道它俩在什么时候使用吗?
lateinit
我们有些时候变量的值在其声明的地方是需要要初始化的。比如,在我们开发中就会遇到一些UI组件在Activity或者是Fragment中的onCreate或者是oncCreateView中才会被初始化的,或者是在需要引用这个UI组件的地方才会被初始化。
class HomeFragment:Fragment(){
private var sureButton:Button? = null
}
在Kotlin中的声明就必须被初始化,但是在Kotlin中又不允许像Java中那样,先声明,到之后才初始化。那么我们在初始化的时候就喜欢让这种变量可空,并且在声明的时候就将该变量置为null。但是我们在使用可空类型的时候,在后续的代码中使用该变量时,我们都必须使用空校验来检查。然后就会出现一连串烦人的问号,如果你刚出Java转向Kotlin开发,这样就会让你的代码看起来特别混乱。
fun initView(){
sureButton?.let{
....
}
}
那么我们怎么在Kotlin中实现和Java那样先声明,再初始化呢?我们就可以使用lateinit修饰符就可以完全做到这一点。
class HomeFragment:Fragment(){
private lateinit var sureButton:Button
}
使用lateinit修饰过后,kotlin将允许你先声明不给它复制。但是该变量必须是可变的var类型,这样Kotlin就会知道你稍后会对这个值进行赋值。通过lateinit修饰符,你可以为变量不适用Kotlin中的空校验。但是如果你忘记了在之后的代码中忘记对lateinit声明的变量进行初始化,就会抛出UninitializedPropertyAccessException的异常
什么时候使用lateinit
- 如果变量是可变的并且可以在稍后阶段初始化。
- 您确定要在使用变量之前对其进行初始化。
- 使用
var关键字.
lazy
在软件工程中有一种常见的模式叫做推迟创建和初始化对象,知道真正需要使用的时候才会创建。这种模式被称为延迟初始化。因为在android中应用在启动期间创建大量对象就会导致启动事件变长。下面就是Java中的延迟初始化
class MyClass {
private HeavyObject heavy;
public HeavyObject getHeavy() {
if (heavy == null) {
heavy = new HeavyObject();
}
return heavy;
}
这种写法当首次需要该值的时候会常见新实例,后续如果再次使用都是使用缓存的实例对象。但是在Kotlin原生语言中是支持延迟初始化的,可以使用by lazy来提供初始化块
class MyClass {
val heavy by lazy { // 初始化块
HeavyObject()
}
}
何时使用by lazy
- 除非你调用它,否则变量不会被初始化。
- 初始化变量一次;然后在整个代码中使用相同的值。
- 在属性的情况下使用,
val即作为同一对象的只读属性将在整个程序中共享。