前言

记录一下Kotlinlateinitby lazy简单使用。

正文

lateinit

为延迟初始化属性。

lateinit用于延迟初始化一个var可变属性。属性类型必须是非空的且不能是原始类型(如 Int, Double)。

经常在类中定义属性时

  1. class Person{
  2.   var name:String;
  3. }
复制

上面会提示

  1. Property must be initialized or be abstract
复制

解决这个可以如下方式

  1. //初始化默认值
  2. var nameA:String = "";
  3. //把Person进行抽象(这肯定不是想要的)
  4. abstract class Person{
  5.   abstract var nameA:String;
  6. }
复制

当然,如果上面两个都不想,那就使用今天的主角lateinit。

复制
使用场景
  1. 需要在构造方法之后初始化的可变属性。

  2. 需要在某个特定操作时才对属性进行赋值。

by lazy

为惰性初始化。

by lazy是一种委托属性,用于延迟初始化一个只读属性。属性在第一次访问时才会被初始化,并且初始化操作只会执行一次。

  1. val property: Type by lazy { initializer }
复制

延迟加载也是委托的一种形式。

  1. val lazyTxt: String by lazy {
  2.   Log.i(TAG,"初始化lazyTxt")
  3.   "lazy"
  4. }
  5. Log.d(TAG, " 1 : $lazyTxt")
  6. Log.d(TAG, " 2 : $lazyTxt")
复制

日志打印

  1. 初始化lazyTxt
  2. 1 : lazy
  3. 2 : lazy
复制

只初始化了一次。

要求属性声明为val,即不可变变量,在java中相当于被final修饰。

使用场景
  1. 需要惰性初始化不可变的属性。

  2. 需要线程安全的初始化或者只在单线程中操作。

小结

特性by lazylateinit
适用类型val(只读属性)var(可变属性)
初始化时间第一次访问时必须手动初始化
线程安全默认线程安全非线程安全
Nullability支持不可空类型支持不可空类型
属性检查不需要显式检查通过isInitialized检查
自定义 getter/setter不支持不支持
使用场景用于只读且惰性初始化的属性用于需要在构造函数之外初始化的可变属性

总结来说,选择使用 by lazy 还是 lateinit 要依据属性的特性和具体的使用场景。

by lazy 更适合不可变的延迟初始化场合,而 lateinit 则适用于在构造方法之后需要手动初始化的可变属性。

参考文章

  1. 浅谈Kotlin(六):lateinit、by lazy 使用

  2. Kotlin之 lateinit 和 by lazy

  3. Android经典面试题之Kotlin延迟初始化的by lazy和lateinit有什么区别?

相关文章

暂无评论

none
暂无评论...