Kotlin延时加载

Kotlin 延时加载核心方案与使用场景


一、延时加载的两种主要实现方式

  1. ‌**lateinit 关键字**‌

    • 适用对象 ‌:仅用于可变变量(var),需手动初始化,适用于非空类型的延迟赋值‌23。

    • 特点‌:

      • 不适用于基本数据类型(如 IntDouble)和 val 常量‌34。
      • 需通过 ::变量名.isInitialized 检查是否已初始化,避免空指针异常‌24。
      复制代码
kotlin 复制代码
class KtBase78 {

   // >>>>>>>>>>>>>>>>>>> 下面是 不使用惰性初始化 by lazy  普通方式(饿汉式 没有任何懒加载的特点)
  val databaseData1 = readSQlServerDatabaseAction()
   private fun readSQlServerDatabaseAction(): String {
       println("开始读取数据库数据中....")
       println("加载读取数据库数据中....")
       println("加载读取数据库数据中....")
       println("加载读取数据库数据中....")
       println("加载读取数据库数据中....")
       println("加载读取数据库数据中....")
       println("加载读取数据库数据中....")
       println("加载读取数据库数据中....")
       println("加载读取数据库数据中....")
       println("结束读取数据库数据中....")
       return "database data load success ok."
   }
}
fun main(){
   // >>>>>>>>>>>>>>>>>>> 下面是 不使用惰性初始化 by lazy  普通方式(饿汉式 没有任何懒加载的特点)
   val p = KtBase78()
   Thread.sleep(5000)
  println("即将开始使用")
  println("最终显示:${p.databaseData1}")
  1. ‌**by lazy 委托**‌

    • 适用对象 ‌:仅用于不可变变量(val),自动延迟初始化,首次访问时执行初始化逻辑‌13。

    • 特点‌:

      • 默认线程安全(LazyThreadSafetyMode.SYNCHRONIZED),支持自定义线程安全模式‌56。
      • 初始化逻辑通过 lambda 表达式定义,最后一行作为返回值‌36。
      复制代码
kotlin 复制代码
package com.lhr.base.s4
class KtBase78 {

   // >>>>>>>>>>>>>>>>>>> 下面是 不使用惰性初始化 by lazy  普通方式(饿汉式 没有任何懒加载的特点)
   val databaseData1 = readSQlServerDatabaseAction()

   val databaseData2 by lazy { readSQlServerDatabaseAction() }

   private fun readSQlServerDatabaseAction(): String {
       println("开始读取数据库数据中....")
       println("加载读取数据库数据中....")
       println("加载读取数据库数据中....")
       println("加载读取数据库数据中....")
       println("加载读取数据库数据中....")
       println("加载读取数据库数据中....")
       println("加载读取数据库数据中....")
       println("加载读取数据库数据中....")
       println("加载读取数据库数据中....")
       println("结束读取数据库数据中....")
       return "database data load success ok."
   }
}
fun main(){
   val p = KtBase78()
   Thread.sleep(5000)
   println("即将开始使用")
   println("最终显示:${p.databaseData2}")


}

上面可以看出,是调用的时候才去初始化

二、使用场景对比

特性 lateinit var by lazyval
可变性 可变(支持重新赋值) 不可变(仅初始化一次)
初始化时机 手动控制(灵活) 首次访问时自动触发(惰性)
适用类型 非空对象(如 String 任意类型(含基本类型)
线程安全 需自行同步 默认线程安全,可配置

三、最佳实践与注意事项

  1. ‌**优先选择 by lazy**‌

    • 适用于只需初始化一次的场景(如单例配置、资源加载),简化代码并减少重复初始化开销‌68。
  2. ‌**lateinit 的使用场景**‌

    • 需要在运行时动态赋值(如依赖注入框架、Activity 中的视图绑定)‌24。
  3. 线程安全处理

    • 多线程环境下,使用 by lazy(LazyThreadSafetyMode.PUBLICATION) 提升性能,或通过同步锁手动控制 lateinit 的初始化‌56。
  4. 避免空指针异常

    • lateinit 变量操作前需检查初始化状态,防止 UninitializedPropertyAccessException‌24。

四、代码示例

kotlin 复制代码
// 使用 lateinit 的视图绑定
class MainActivity : AppCompatActivity() {
    lateinit var binding: ActivityMainBinding

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        binding = ActivityMainBinding.inflate(layoutInflater)
        setContentView(binding.root)
    }
}

// 使用 by lazy 的单例配置
object AppConfig {
    val apiKey by lazy { readApiKeyFromEnv() }
}

// 线程安全的延迟初始化
val sharedData: List<String> by lazy(LazyThreadSafetyMode.NONE) {
    fetchDataConcurrently() // 非阻塞式初始化
}

总结 ‌:Kotlin 通过 lateinitby lazy 提供灵活的延时加载方案。若需动态赋值或生命周期控制,选择 lateinit;若需自动初始化且保证线程安全,优先使用 by lazy

相关推荐
alexhilton12 小时前
Android的Agent优先时代:构建时vs运行时
android·kotlin·android jetpack
Cutecat_13 小时前
视频字幕处理工具横向:提取模式 vs 编辑模式,该如何选择
android·前端·ios·语音识别
2601_9617652914 小时前
【分享】PlayerPro媒体音乐播放器 完整专业版
android·媒体
JohnnyDeng9416 小时前
【Android】Android 包体积优化:R8/ProGuard 深度配置全攻略
android·性能优化·kotlin·jetpack
故渊at16 小时前
第九板块:Android 多媒体体系 | 第二十四篇:Camera Service 与 HAL3 成像流水线
android·camera·多媒体体系·hal3
Jinkxs20 小时前
Python基础 - 初识内置函数 Python自带的便捷工具
android·java·python
私人珍藏库20 小时前
【Android】VLLO-韩国热门手机剪辑APP
android·app·工具·软件·多功能
Cloud_Shy61821 小时前
解读《Effective Python 3rd Edition》:从练气到老魔(第六章 Item 40 - 43)
android·开发语言·人工智能·笔记·python·学习方法
AFinalStone21 小时前
Android12 U盘插拔链路源码全解析(五):Framework层(下) StorageManagerService
android·frameworks
林九生1 天前
【实用技巧】MySQL 绿色版一键路径更新脚本详解 —— update_path.bat 深度解析
android·数据库·mysql