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

相关推荐
常利兵17 分钟前
Android内存泄漏:成因剖析与高效排查实战指南
android
·云扬·20 分钟前
MySQL 8.0 Redo Log 归档与禁用实战指南
android·数据库·mysql
野生技术架构师22 分钟前
SQL语句性能优化分析及解决方案
android·sql·性能优化
doupoa2 小时前
内存指针是什么?为什么指针还要有偏移量?
android·c++
非凡ghost2 小时前
PowerDirector安卓版(威力导演安卓版)
android·windows·学习·软件需求
独行soc3 小时前
2026年渗透测试面试题总结-19(题目+回答)
android·网络·安全·web安全·渗透测试·安全狮
爱装代码的小瓶子4 小时前
【C++与Linux基础】进程间通讯方式:匿名管道
android·c++·后端
兴趣使然HX5 小时前
Android绘帧流程解析
android
JMchen1236 小时前
Android UDP编程:实现高效实时通信的全面指南
android·经验分享·网络协议·udp·kotlin
黄林晴6 小时前
Android 17 再曝猛料:通知栏和快捷设置终于分家了,这操作等了十年
android