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

相关推荐
“初生”1 小时前
安卓手机安装 ChatGPT 全流程图文指南
android·chatgpt·智能手机
与籍同行1 小时前
20200201工作笔记常用命令要整理
android·笔记
tangweiguo030519872 小时前
Android屏幕适配利器:Kotlin动态尺寸计算工具类完整封装
android·kotlin
aningxiaoxixi3 小时前
android property 系统
android
speop3 小时前
TASK05【Datawhale 组队学习】系统评估与优化
android·java·学习
zhu62019766 小时前
Android10如何设置ro.debuggable=1?
android·安全·android逆向·android10·ro.debuggable
androidwork6 小时前
Android 内存溢出(OOM)的 Kotlin 排查与优化指南
android·开发语言·kotlin
xzkyd outpaper7 小时前
Android中PID与UID的区别和联系
android·计算机八股
Developings7 小时前
Android logcat命令汇总
android
吃着火锅x唱着歌7 小时前
PHP7内核剖析 学习笔记 第八章 命名空间
android·笔记·学习