当前位置: 首页 > news >正文

Kotlin -> lateinit 和 lazy 详解

lateinitlazy 详解

核心区别

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

lateinit 核心用法

// 声明
class User {lateinit var name: Stringfun initialize() {name = "John" // 手动初始化}fun greet() {if (::name.isInitialized) { // 检查是否已初始化println("Hello, $name")}}
}

最佳使用场景:

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

lazy 核心用法

// 基本用法
class User {val name: String by lazy { println("Computing name...")"John" // 计算并返回初始值}
}// 指定线程安全模式
val expensiveData: List<Data> by lazy(LazyThreadSafetyMode.PUBLICATION) {loadDataFromDatabase()
}

线程安全模式:

  • SYNCHRONIZED:默认模式,线程安全,只执行一次初始化
  • PUBLICATION:多线程可能执行多次,但只有第一个结果被使用
  • NONE:不保证线程安全,适用于单线程环境,性能最好

最佳使用场景:

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

核心实现原理

lateinit

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

lazy

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

如何选择

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

相关文章:

  • 聚焦智能体未来,领驭科技在微软创想未来峰会大放异彩
  • 按键精灵安卓ios辅助工具脚本:实用的文件插件(lua开源)
  • 私有知识库 Coco AI 实战(四):打造 ES 索引参数小助手
  • 前端漏洞不扫描理由
  • Linux systemd 从理论到实践:现代系统管理的核心工具
  • C++ 单例对象自动释放(保姆级讲解)
  • Hearts of Iron IV 钢铁雄心 4 [DLC 解锁] [Windows SteamOS macOS]
  • 机器学习-入门-决策树(1)
  • 第17节:传统分类模型-随机森林与决策树
  • day10 python机器学习全流程实践
  • Azure Synapse Dedicated SQL pool企业权限管理
  • 数据库操作
  • 轻松实现CI/CD: 用Go编写的命令行工具简化Jenkins构建
  • Java练习8
  • 【AlphaFold2】Feature extraction:提取特征,为模型输入做准备|Datapipeline讲解
  • 激光扫描仪的用途及优势
  • Java常用注解通俗解释
  • 【计算机视觉】目标检测:深度解析YOLOv5:下一代实时目标检测框架实战指南
  • UniApp 小程序嵌套 H5 页面显示隐藏监听实践
  • CentOS NFS共享目录
  • 新开发银行如何开启第二个“金色十年”?
  • 初步结果显示加拿大自由党赢得大选,外交部回应
  • 金融街:去年净亏损约110亿元,今年努力实现经营稳健和财务安全
  • 泽连斯基承认乌情报部门刺杀俄军高官
  • 吕国范任河南省人民政府副省长
  • 新任浙江省委常委、杭州市委书记刘非开展循迹溯源学习调研