Kotlin系列(二十四):秘技之延迟属性
- 更多分享:www.catbro.cn
一、前言:
- 我们在上一篇学习了Kotlin的委托属性的使用及原理。
- 本章我们将学习基于委托属性而演变出来的非常使用的一个属性-延迟属性;
- 延迟属性也是Kotlin标准库中提供的工厂方法之一;
二、延迟属性: Lazy
-
用法很简单,你只需要记住Lazy关键字即可。
-
lazy() 是接受一个 lambda 并返回一个
Lazy <T>
实例的函数,返回的实例可以作为实现延迟属性的委托: -
第一次调用 get() 会执行已传递给 lazy() 的 lambda 表达式并记录结果,后续调用 get() 只是返回记录的结果。
-
测试代码如下
val lazyValue: String by lazy { println("computed!") "Anjie" } @Test fun test1() { println(lazyValue) println(lazyValue) }
-
结果输出为:
computed! Anjie Anjie
-
默认情况下,对于 lazy 属性的求值是同步锁的(synchronized):该值只在一个线程中计算,并且所有线程会看到相同的值。
-
如果初始化委托的同步锁不是必需的,这样多个线程可以同时执行,那么将
LazyThreadSafetyMode.PUBLICATION
作为参数传递给lazy()
函数。 -
而如果你确定初始化将总是发生在单个线程,那么你可以使用
LazyThreadSafetyMode.NONE
模式,它不会有任何线程安全的保证和相关的开销。 -
懒加载的源码我们就不看了,本章节作为基础文章,太深入反而不好,但是我们可以从原理上猜测一番。
-
1、lazy后面为什么会跟一个lambada函数呢?其实你可以把他当作闭包,这样子就很好理解了。
-
为什么呢?因为闭包可以有自己的管理区域,其也能捕获外部变量,最主要的是,利用其延迟调用的方式似乎便可实现我们的延迟加载了。
-
2、根据前面对委托属性的分析,我们大可假设,当我们调用延迟属性的时候,其getter内部会调用一个代理类的某个方法,该代理类是kotlin自动生成,且与lazy有关,所以代理类掌握着我们的lambada函数。
-
3、其内部可以做判断,当我们第一次调用时,其就执行lambada函数并记录返回的值,当下次调用时,直接返回即可。
-
4、当然,当多个线程同时调用时,是否就混乱了呢?所以kotlin为我们提供了默认的线程安全的配置,当然你也可以根据自己的实际情况来配置为线程非安全的。
-
以上便是我大胆而不实际的猜测,感谢您的观看。