前言
记录一下Kotlin中lateinit和by lazy简单使用。
正文
lateinit
为延迟初始化属性。
lateinit用于延迟初始化一个var可变属性。属性类型必须是非空的且不能是原始类型(如 Int, Double)。
经常在类中定义属性时
- class Person{
- var name:String;
- }
上面会提示
- Property must be initialized or be abstract
解决这个可以如下方式
- //初始化默认值
- var nameA:String = "";
-
- //把Person进行抽象(这肯定不是想要的)
- abstract class Person{
- abstract var nameA:String;
- }
使用场景
需要在构造方法之后初始化的可变属性。
需要在某个特定操作时才对属性进行赋值。
by lazy
为惰性初始化。
by lazy是一种委托属性,用于延迟初始化一个只读属性。属性在第一次访问时才会被初始化,并且初始化操作只会执行一次。
- val property: Type by lazy { initializer }
延迟加载也是委托的一种形式。
- val lazyTxt: String by lazy {
- Log.i(TAG,"初始化lazyTxt")
- "lazy"
- }
- Log.d(TAG, " 1 : $lazyTxt")
- Log.d(TAG, " 2 : $lazyTxt")
日志打印
- 初始化lazyTxt
- 1 : lazy
- 2 : lazy
只初始化了一次。
要求属性声明为val,即不可变变量,在java中相当于被final修饰。
使用场景
需要惰性初始化不可变的属性。
需要线程安全的初始化或者只在单线程中操作。
小结
特性 | by lazy | lateinit |
---|---|---|
适用类型 | val(只读属性) | var(可变属性) |
初始化时间 | 第一次访问时 | 必须手动初始化 |
线程安全 | 默认线程安全 | 非线程安全 |
Nullability | 支持不可空类型 | 支持不可空类型 |
属性检查 | 不需要显式检查 | 通过isInitialized检查 |
自定义 getter/setter | 不支持 | 不支持 |
使用场景 | 用于只读且惰性初始化的属性 | 用于需要在构造函数之外初始化的可变属性 |
总结来说,选择使用 by lazy 还是 lateinit 要依据属性的特性和具体的使用场景。
by lazy 更适合不可变的延迟初始化场合,而 lateinit 则适用于在构造方法之后需要手动初始化的可变属性。
参考文章
《》
《》
《
© 版权声明