Kotlin -> lateinit 和 lazy 详解

打印 上一主题 下一主题

主题 1661|帖子 1661|积分 4983

马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。

您需要 登录 才可以下载或查看,没有账号?立即注册

x
lateinit 和 lazy 详解

核心区别

特性lateinitlazy类型可变属性修饰符 var不可变属性委托 val初始化时机手动显式初始化,随时可变首次访问时自动初始化,之后不可变空安全非空类型,但初始值可缺失非空类型,包管有值适用类型不能用于基本类型(Int, Boolean等)可用于任何类型线程安全不包管线程安全默认线程安全SYNCHRONIZED模式检查机制利用前需确保已初始化,否则抛非常自动处理初始化,不会抛出未初始化非常 lateinit 核心用法

  1. // 声明
  2. class User {
  3.     lateinit var name: String
  4.    
  5.     fun initialize() {
  6.         name = "John" // 手动初始化
  7.     }
  8.    
  9.     fun greet() {
  10.         if (::name.isInitialized) { // 检查是否已初始化
  11.             println("Hello, $name")
  12.         }
  13.     }
  14. }
复制代码
最佳利用场景:



  • 依赖注入
  • Activity/Fragment中的视图绑定
  • 单元测试的setUp方法中
  • 需要推迟初始化但之后可能需要修改的属性
lazy 核心用法

  1. // 基本用法
  2. class User {
  3.     val name: String by lazy {
  4.         println("Computing name...")
  5.         "John" // 计算并返回初始值
  6.     }
  7. }
  8. // 指定线程安全模式
  9. val expensiveData: List<Data> by lazy(LazyThreadSafetyMode.PUBLICATION) {
  10.     loadDataFromDatabase()
  11. }
复制代码
线程安全模式:



  • SYNCHRONIZED:默认模式,线程安全,只执行一次初始化
  • PUBLICATION:多线程可能执行多次,但只有第一个效果被利用
  • NONE:不包管线程安全,适用于单线程情况,性能最好
最佳利用场景:



  • 盘算开销大的属性
  • 需要根据条件盘算的只读属性
  • 单例模式实现
  • 配置项和缓存数据
核心实现原理

lateinit



  • 在字节码级别,不为属性分配默认值
  • 访问前不举行空检查
  • 利用前若未初始化,抛出UninitializedPropertyAccessException
lazy



  • 内部利用SynchronizedLazyImpl等实现类
  • 持有一个初始化器函数和一个存储效果的AtomicReference
  • 首次访问时执行初始化器并缓存效果
如何选择



  • 假如属性需要在初始化后修改,利用lateinit var
  • 假如属性是只读的且可以延迟盘算,利用lazy val
  • 假如处理基本类型,只能利用lazy
  • 假如在多线程情况中,优先考虑lazy

免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。
回复

使用道具 举报

0 个回复

倒序浏览

快速回复

您需要登录后才可以回帖 登录 or 立即注册

本版积分规则

灌篮少年

论坛元老
这个人很懒什么都没写!
快速回复 返回顶部 返回列表