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

相关推荐
ŧ榕树先生6 小时前
稳定的Android studio版本安装教程
android·ide·android studio
早上好啊! 树哥7 小时前
常见的文件加密方式之【异或加密】,代入原理看例子,帮助更好的理解。
android·java·junit
沅霖8 小时前
Android: Handler 的用法详解
android
鸿蒙布道师8 小时前
鸿蒙NEXT开发数值工具类(TS)
android·ios·华为·harmonyos·arkts·鸿蒙系统·huawei
Yang-Never10 小时前
Open GL ES ->GLSurfaceView在正交投影下的图片旋转、缩放、位移
android·开发语言·kotlin·android studio·贴图
粤M温同学10 小时前
使用Android 原生LocationManager获取经纬度
android
stevenzqzq10 小时前
Android Hilt 教程
android
CYRUS_STUDIO10 小时前
Frida Stalker Trace 指令跟踪&寄存器变化监控
android·逆向·汇编语言
bst@微胖子10 小时前
Flutter之设计与主题&字体
android·flutter
深圳之光12 小时前
增加android 禁用相机后摄的接口
android·数码相机