by lazy 是 Kotlin 中用于属性委托(property delegation)的一个非常有用的关键字。它允许懒加载(lazy initialization)一个属性,即只有在首次访问该属性时才进行初始化,并且一旦初始化完成,后续的访问将直接使用缓存的值。这在需要延迟初始化资源或者计算开销较大的情况下特别有用。
by lazy 的用法
by lazy 接受一个 lambda 表达式作为参数,这个表达式定义了属性的初始化逻辑。默认情况下,by lazy 初始化是线程安全的,并且只执行一次。你可以通过传递不同的参数来改变它的行为。
语法:
val <propertyName>: <PropertyType> by lazy {
// 属性初始化逻辑
}
参数选项:
- mode: 可以指定为
LazyThreadSafetyMode.SYNCHRONIZED(默认,线程安全)、LazyThreadSafetyMode.PUBLICATION(允许多次初始化但最终只会保留第一次的结果,线程安全)或LazyThreadSafetyMode.NONE(非线程安全,适用于单线程环境)。 - initializer: 一个 lambda 表达式,定义了属性的初始化逻辑。
示例代码
假设我们有一个需要在首次访问时从网络加载数据的属性,我们可以使用 by lazy 来实现懒加载:
class DataFetcher {
// 懒加载属性,仅在首次访问时执行初始化逻辑
val data: String by lazy {
println("Loading data from network...")
fetchDataFromNetwork() // 模拟网络请求
}
private fun fetchDataFromNetwork(): String {
// 模拟网络请求,返回数据
return "Fetched Data"
}
}
fun main() {
val fetcher = DataFetcher()
// 此时不会加载数据
println("Before accessing 'data' property.")
// 首次访问 'data' 属性时,会触发初始化逻辑
println(fetcher.data) // 输出: Loading data from network... Fetched Data
// 再次访问 'data' 属性,直接返回缓存的值
println(fetcher.data) // 输出: Fetched Data
}
在这个例子中,data 属性直到第一次被访问时才会调用 fetchDataFromNetwork() 方法去获取数据。之后的所有访问都会直接返回之前缓存的数据,而不会再执行初始化逻辑。
自定义线程安全模式
如果应用是在单线程环境中运行,或者不关心多次初始化的风险,可以使用 LazyThreadSafetyMode.NONE 来提高性能:
val data: String by lazy(LazyThreadSafetyMode.NONE) {
println("Loading data from network...")
fetchDataFromNetwork()
}
实际应用场景
by lazy 在以下场景中尤其有用:
- 当属性的初始化开销较大,但是不一定每次都需要访问的时候。
- 当属性依赖于其他可能尚未准备好初始化的资源时。
- 当需要确保某个昂贵的操作只执行一次,并且结果可以在整个生命周期内复用时。
通过合理地使用 by lazy,可以使代码更加简洁、高效,并且减少不必要的资源消耗。
当前文章价值8.68元,扫一扫支付后添加微信提供帮助!(如不能解决您的问题,可以申请退款)

评论已关闭!