Download as pdf or txt
Download as pdf or txt
You are on page 1of 3

实现⼀个 lazy 函数

实现
// 默认值
internal object DEFAULT_VALUE

// 定义 Lazy 接⼝
interface FakeLazy<out T> {
public val value: T
// 是否初始化
public fun isInitialized(): Boolean
}

// 对外函数
fun <T> fakeLazy(initializer: () -> T): FakeLazy<T> = FakeLazyImpl(initializer)

// 对外扩展函数
// by fakeLazy {}
operator fun <T> FakeLazy<T>.getValue(thisRef: Any?, property: KProperty<*>): T =
value

// Lazy 实现类
// 线程安全🔐
@Suppress("UNCHECKED_CAST")
class FakeLazyImpl<out T>(private var initializer: (() -> T)?) : FakeLazy<T> {

@Volatile
private var _value: Any? = DEFAULT_VALUE
private val lock = this

override val value: T


get() {
// 第⼀步
// ⾸先判断当前的 value 是否是默认值
// 如果不是说明已经初始化过,直接返回
val _v1 = _value
if (_v1 !== DEFAULT_VALUE) {
return _v1 as T
}
synchronized(lock) {
// 第⼆步
// 加锁后,重复第⼀步判断
val _v2 = _value
if (_v2 !== DEFAULT_VALUE) {
return _v2 as T
} else {
// 第三步
// 以上条件都不满⾜,说明还未初始化
// 调⽤ initializer 函数进⾏初始化
val _v3 = initializer!!()
// 将初始化后的值赋给 value

1
实现⼀个 lazy 函数

_value = _v3
// 将初始化函数置空
initializer = null
return _v3
}
}
}

override fun isInitialized(): Boolean = _value !== DEFAULT_VALUE

使⽤
class FakeLazyDemo {

val instance by fakeLazy {


FakeLazyDemo()
}

原理
将上述代码反编译为 Java 代码

public final class FakeLazyDemo {


// $FF: synthetic field
static final KProperty[] $$delegatedProperties = new KProperty[]
{(KProperty)Reflection.property1(new
PropertyReference1Impl(Reflection.getOrCreateKotlinClass(FakeLazyDemo.class),
"instance", "getInstance()Lcom/application/FakeLazyDemo;"))};
@NotNull
private final FakeLazy instance$delegate;

@NotNull
public final FakeLazyDemo getInstance() {
return (FakeLazyDemo)FakeLazyKt.getValue(this.instance$delegate, this, $
$delegatedProperties[0]);
}

public FakeLazyDemo() {
this.instance$delegate = FakeLazyKt.fakeLazy((Function0)null.INSTANCE);
}
}

2
实现⼀个 lazy 函数

根据代码可以看到

- ⽣成⼀个该属性的附加属性: instance$delegate
- 在构造器中,将使⽤ lazy(()->T) 创建的 Lazy 实例对象赋值给
instance$delegate
- 当该属性被调⽤,即其 getInstance() ⽅法被调⽤时返回
FakeLazyKt.getValue(thisRef, property) ,⽽这个⽅法的返回结果是对象
instance$delegate 内部的 _value 属性值,在 getValue() 第⼀次被调⽤时会将
_value 进⾏初始化,往后都是直接将 _value 的值返回,从⽽实现属性值的唯
⼀⼀次初始化。

You might also like