Kotlin 延时加载核心方案与使用场景
一、延时加载的两种主要实现方式
-
**
lateinit
关键字**-
适用对象 :仅用于可变变量(
var
),需手动初始化,适用于非空类型的延迟赋值23。 -
特点:
- 不适用于基本数据类型(如
Int
、Double
)和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}")

-
**
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 lazy (val ) |
---|---|---|
可变性 | 可变(支持重新赋值) | 不可变(仅初始化一次) |
初始化时机 | 手动控制(灵活) | 首次访问时自动触发(惰性) |
适用类型 | 非空对象(如 String ) |
任意类型(含基本类型) |
线程安全 | 需自行同步 | 默认线程安全,可配置 |
三、最佳实践与注意事项
-
**优先选择
by lazy
**- 适用于只需初始化一次的场景(如单例配置、资源加载),简化代码并减少重复初始化开销68。
-
**
lateinit
的使用场景**- 需要在运行时动态赋值(如依赖注入框架、Activity 中的视图绑定)24。
-
线程安全处理
- 多线程环境下,使用
by lazy(LazyThreadSafetyMode.PUBLICATION)
提升性能,或通过同步锁手动控制lateinit
的初始化56。
- 多线程环境下,使用
-
避免空指针异常
- 对
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 通过
lateinit
和by lazy
提供灵活的延时加载方案。若需动态赋值或生命周期控制,选择lateinit
;若需自动初始化且保证线程安全,优先使用by lazy