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

相关推荐
百锦再3 小时前
Android Studio开发中Application和Activity生命周期详解
android·java·ide·app·gradle·android studio·studio
移动开发者1号4 小时前
Android现代进度条替代方案
android·app
万户猴4 小时前
【Android蓝牙开发实战-11】蓝牙BLE多连接机制全解析1
android·蓝牙
RichardLai884 小时前
[Flutter 基础] - Flutter基础组件 - Icon
android·flutter
前行的小黑炭4 小时前
Android LiveData源码分析:为什么他刷新数据比Handler好,能更节省资源,解决内存泄漏的隐患;
android·kotlin·android jetpack
清霜之辰4 小时前
安卓 Compose 相对传统 View 的优势
android·内存·性能·compose
_祝你今天愉快4 小时前
再看!NDK交叉编译动态库并在Android中调用
android
一杯凉白开4 小时前
Android View 事件的分发机制 四句口诀 先问拦截再派送,子不处理父兜底, 一旦消费无后续, 滑动冲突靠逻辑。
android
冬田里的一把火34 小时前
[Android]导航栏中插入电源菜单
android
星途码客5 小时前
SQLyog中DELIMITER执行存储过程时出现的前置缩进问题
android