- 核心思想
- 饿汉式的属性代理
- 懒汉式的属性代理
- 示例代码
一、核心思想
当我们对属性进行赋值时会触发属性的重载运算符函数setValue
,而获取属性值时又会触发属性重载运算符函数getValue
,所以只要重载定义属性的setValue
和getValue
方法,并在此方法中调用实际操作对象,就可以实现对其它方法及属性的代理。
二、饿汉式的属性代理
- 应用场景:在代理此对象的时候,此对象已经被创建并能够获取到的情况。
-
无Reciever:主要应对
T()::KProperty \ T()::KFunction
、以及顶级属性和方法的情况。
1、仅提供Getter代理
// 通用创建Getter代理
fun <T> delegateOf(getter: () -> T): ReadOnlyProperty<Any, T> = Delegate0GetterOf(getter)
// 属性快捷创建Getter代理
fun <T> KProperty0<T>.delegator(): ReadOnlyProperty<Any, T> = Delegate0GetterOf(this)
// 方法快捷创建Getter代理
@JvmName("delegateGetter")
fun <R> KFunction0<R>.delegator(): ReadOnlyProperty<Any, R> = Delegate0GetterOf(this)
internal class Delegate0GetterOf<T>(private val getter: () -> T) : ReadOnlyProperty<Any, T>,
Serializable {
constructor(property: KProperty0<T>) : this(property::get)
override fun getValue(thisRef: Any, property: KProperty<*>): T = getter.invoke()
}
2、仅提供Setter代理
// 通用创建Setter代理
fun <T> delegateOf(
setter: (T) -> Unit,
initializedValue: T? = null
): WriteOnlyProperty<T> = Delegate0SetterOf(setter, initializedValue)
// 方法快捷创建Setter代理
@JvmName("delegateSetter")
fun <T> KFunction1<T, Unit>.delegator(initializedValue: T? = null): WriteOnlyProperty<T> =
Delegate0SetterOf(this, initializedValue)
abstract class WriteOnlyProperty<V> : ReadWriteProperty<Any, V> {
final override fun getValue(thisRef: Any, property: KProperty<*>): V =
throw NoSuchMethodException("The value of ${property.name} can't be get!")
}
internal class Delegate0SetterOf<T>(
private val setter: (T) -> Unit,
initializedValue: T? = null
) : WriteOnlyProperty<T>(), Serializable {
constructor(property: KMutableProperty0<T>, initializedValue: T? = null)
: this(property::set, initializedValue)
init {
initializedValue?.also { setter.invoke(it) }
}
override fun setValue(thisRef: Any, property: KProperty<*>, value: T) = setter.invoke(value)
}
3、仅提供Getter、Setter代理
// 通用创建Getter、Setter代理
fun <T> delegateOf(
getter: () -> T,
setter: (T) -> Unit,
initializedValue: T? = null
): ReadWriteProperty<Any, T> = Delegate0Of(getter, setter, initializedValue)
// 属性快捷创建Getter、Setter代理
fun <T> KMutableProperty0<T>.delegator(initializedValue: T? = null): ReadWriteProperty<Any, T> =
Delegate0Of(this, initializedValue)
internal class Delegate0Of<T>(
private val getter: () -> T,
private val setter: (T) -> Unit,
initializedValue: T? = null
) : ReadWriteProperty<Any, T>, Serializable {
constructor(property: KMutableProperty0<T>, initializedValue: T? = null)
: this(property::get, property::set, initializedValue)
init {
initializedValue?.also { setter.invoke(it) }
}
override fun getValue(thisRef: Any, property: KProperty<*>): T = getter.invoke()
override fun setValue(thisRef: Any, property: KProperty<*>, value: T) = setter.invoke(value)
}
-
有Reciever:主要应对
T::KProperty \ T::KFunction
的情况。
1、仅提供Getter代理
// 通用创建Getter代理
fun <T, R> delegateOf(receiver: R, getter: (R) -> T): ReadOnlyProperty<Any, T> =
DelegateGetterOf(receiver, getter)
// 属性快捷创建Getter代理
fun <T, R> KProperty1<R, T>.delegator(receiver: R): ReadOnlyProperty<Any, T> =
DelegateGetterOf(receiver, this)
// 方法快捷创建Getter代理
@JvmName("delegateGetter")
fun <T, R> KFunction1<R, T>.delegator(receiver: R): ReadOnlyProperty<Any, T> =
DelegateGetterOf(receiver, this)
internal class DelegateGetterOf<T, R>(override val receiver: R, getter: (R) -> T) :
AbsObjectGetterPropertyDelegate1<R, T>(getter) {
constructor(receiver: R, property: KProperty1<R, T>) : this(receiver, property::get)
}
internal abstract class AbsObjectGetterPropertyDelegate1<R, T>(
private val getter: (R) -> T
) : ReadOnlyProperty<Any, T>, Serializable {
protected abstract val receiver: R
final override fun getValue(thisRef: Any, property: KProperty<*>): T = getter.invoke(receiver)
}
2、仅提供Setter代理
// 通用创建Setter代理
fun <T, R> delegateOf(
receiver: R,
setter: (R, T) -> Unit,
initializedValue: T? = null
): WriteOnlyProperty<T> = DelegateSetterOf(receiver, setter, initializedValue)
// 方法快捷创建Setter代理
@JvmName("delegateSetter")
fun <R, T> KFunction2<R, T, Unit>.delegator(receiver: R, initializedValue: T? = null)
: WriteOnlyProperty<T> = DelegateSetterOf(receiver, this, initializedValue)
internal class DelegateSetterOf<T, R>(
override val receiver: R,
setter: (R, T) -> Unit,
initializedValue: T? = null
) : AbsObjectSetterPropertyDelegate1<R, T>(setter) {
constructor(receiver: R, property: KMutableProperty1<R, T>, initializedValue: T? = null)
: this(receiver, property::set, initializedValue)
init {
initializedValue?.also { setter.invoke(receiver, it) }
}
}
internal abstract class AbsObjectSetterPropertyDelegate1<R, T>(
private val setter: (R, T) -> Unit
) : WriteOnlyProperty<T>(), Serializable {
protected abstract val receiver: R
override fun setValue(thisRef: Any, property: KProperty<*>, value: T) =
setter.invoke(receiver, value)
}
3、仅提供Getter、Setter代理
// 通用创建Getter、Setter代理
fun <T, R> delegateOf(
receiver: R,
getter: (R) -> T,
setter: (R, T) -> Unit,
initializedValue: T? = null
): ReadWriteProperty<Any, T> = DelegateOf(receiver, getter, setter, initializedValue)
// 属性快捷创建Getter、Setter代理
fun <T, R> KMutableProperty1<R, T>.delegator(
receiver: R,
initializedValue: T? = null
): ReadWriteProperty<Any, T> = DelegateOf(receiver, this, initializedValue)
internal class DelegateOf<T, R>(
override val receiver: R,
getter: (R) -> T,
setter: (R, T) -> Unit,
initializedValue: T? = null
) : AbsObjectPropertyDelegate1<R, T>(getter, setter) {
constructor(receiver: R, property: KMutableProperty1<R, T>, initializedValue: T? = null)
: this(receiver, property::get, property::set, initializedValue)
init {
initializedValue?.also { setter.invoke(receiver, it) }
}
}
internal abstract class AbsObjectPropertyDelegate1<R, T>(
private val getter: (R) -> T,
private val setter: (R, T) -> Unit
) : ReadWriteProperty<Any, T>, Serializable {
protected abstract val receiver: R
final override fun getValue(thisRef: Any, property: KProperty<*>): T = getter.invoke(receiver)
final override operator fun setValue(thisRef: Any, property: KProperty<*>, value: T) =
setter.invoke(receiver, value)
}
三、懒汉式的属性代理
- 应用场景:在代理此对象的时候,此对象未被创建 或 创建了暂时获取不到的情况。
// 如android中这种情况
val name by delegateLazyOf(TextView::getText, TextView::setText) {
findViewById<TextView>(R.id.textview)
}
private val listener: (Button, View.OnClickListener) -> Unit = Button::setOnClickListener
var continuationListener by delegateLazyOf(listener) {
findViewById<Button>(R.id.continuation)
}
-
Reciever需要懒加载:主要应对
T::KProperty \ T::KFunction
,并且reciever在调用时才加载的情况。
1、仅提供Getter代理
// 通用创建Getter代理
fun <T, R> delegateLazyOf(getter: (R) -> T, lazyReceiver: () -> R): ReadOnlyProperty<Any, T> =
DelegateGetterLazyOf(lazyReceiver, getter)
// 属性快捷创建Getter代理
fun <T, R> KProperty1<R, T>.delegatorLazy(lazyReceiver: () -> R): ReadOnlyProperty<Any, T> =
DelegateGetterLazyOf(lazyReceiver, this)
// 方法快捷创建Getter代理
@JvmName("delegateGetterLazy")
fun <T, R> KFunction1<R, T>.delegatorLazy(lazyReceiver: () -> R): ReadOnlyProperty<Any, T> =
DelegateGetterLazyOf(lazyReceiver, this)
internal class DelegateGetterLazyOf<T, R>(
lazyReceiver: () -> R,
getter: (R) -> T
) : AbsObjectGetterPropertyDelegate1<R, T>(getter) {
constructor(lazyReceiver: () -> R, property: KProperty1<R, T>)
: this(lazyReceiver, property::get)
override val receiver: R by lazy { lazyReceiver() }
}
internal abstract class AbsObjectGetterPropertyDelegate1<R, T>(
private val getter: (R) -> T
) : ReadOnlyProperty<Any, T>, Serializable {
protected abstract val receiver: R
final override fun getValue(thisRef: Any, property: KProperty<*>): T = getter.invoke(receiver)
}
2、仅提供Setter代理
// 通用创建Setter代理
fun <T, R> delegateLazyOf(
setter: (R, T) -> Unit,
initializedValue: T? = null,
lazyReceiver: () -> R
): WriteOnlyProperty<T> = DelegateSetterLazyOf(lazyReceiver, setter, initializedValue)
// 方法快捷创建Setter代理
@JvmName("delegateSetterLazy")
fun <T, R> KFunction2<R, T, Unit>.delegatorLazy(
initializedValue: T? = null,
lazyReceiver: () -> R
): WriteOnlyProperty<T> = DelegateSetterLazyOf(lazyReceiver, this, initializedValue)
internal class DelegateSetterLazyOf<T, R>(
lazyReceiver: () -> R,
setter: (R, T) -> Unit,
initializedValue: T? = null
) : AbsObjectSetterPropertyDelegate1<R, T>(setter) {
constructor(lazyReceiver: () -> R, property: KMutableProperty1<R, T>)
: this(lazyReceiver, property::set)
override val receiver: R by lazy {
lazyReceiver().also { receiver ->
initializedValue?.let { setter.invoke(receiver, it) }
}
}
}
internal abstract class AbsObjectSetterPropertyDelegate1<R, T>(
private val setter: (R, T) -> Unit
) : WriteOnlyProperty<T>(), Serializable {
protected abstract val receiver: R
override fun setValue(thisRef: Any, property: KProperty<*>, value: T) =
setter.invoke(receiver, value)
}
abstract class WriteOnlyProperty<V> : ReadWriteProperty<Any, V> {
final override fun getValue(thisRef: Any, property: KProperty<*>): V =
throw NoSuchMethodException("The value of ${property.name} can't be get!")
}
3、仅提供Getter、Setter代理
// 通用创建Getter、Setter代理
fun <T, R> delegateLazyOf(
getter: (R) -> T,
setter: (R, T) -> Unit,
initializedValue: T? = null,
lazyReceiver: () -> R
): ReadWriteProperty<Any, T> = DelegateLazyOf(lazyReceiver, getter, setter, initializedValue)
// 属性快捷创建Getter、Setter代理
fun <T, R> KMutableProperty1<R, T>.delegatorLazy(
initializedValue: T? = null,
lazyReceiver: () -> R
): ReadWriteProperty<Any, T> = DelegateLazyOf(lazyReceiver, this, initializedValue)
internal class DelegateLazyOf<T, R>(
lazyReceiver: () -> R,
getter: (R) -> T,
setter: (R, T) -> Unit,
initializedValue: T? = null
) : AbsObjectPropertyDelegate1<R, T>(getter, setter) {
constructor(
lazyReceiver: () -> R,
property: KMutableProperty1<R, T>,
initializedValue: T? = null
) : this(lazyReceiver, property::get, property::set, initializedValue)
override val receiver: R by lazy {
lazyReceiver().also { receiver ->
initializedValue?.let { setter.invoke(receiver, it) }
}
}
}
internal abstract class AbsObjectPropertyDelegate1<R, T>(
private val getter: (R) -> T,
private val setter: (R, T) -> Unit
) : ReadWriteProperty<Any, T>, Serializable {
protected abstract val receiver: R
final override fun getValue(thisRef: Any, property: KProperty<*>): T = getter.invoke(receiver)
final override operator fun setValue(thisRef: Any, property: KProperty<*>, value: T) =
setter.invoke(receiver, value)
}
四、示例代码
// RealClazz
class RealClazz(var name: String) {
val age: Int = 18
private var value: Int = 0
fun setScore(score: Int) { this.value = score }
fun getScore(): Int = this.value
override fun toString() = "[name=$name, age=$age, score=$value]"
}
object Person {
private val realClazz = RealClazz("小明")
fun printlnRealClazz() = println(realClazz)
// --- 无接收者,饿汉式代理 ------------------------------------------
val age by delegateOf(realClazz::age::get)
var nameSetter by delegateOf(realClazz::name::set)
var name by delegateOf(realClazz::name::get, realClazz::name::set)
// -- 属性 --
val ageProperty by realClazz::age.delegator()
var nameProperty by realClazz::name.delegator()
// -- 方法 --
val scoreGetter by realClazz::getScore.delegator()
var scoreSetter by realClazz::setScore.delegator()
// --- 有接收者,饿汉式代理 ------------------------------------------
val rAge by delegateOf(realClazz, RealClazz::age::get)
var rNameSetter by delegateOf(realClazz, RealClazz::name::set)
var rName by delegateOf(realClazz, RealClazz::name::get, RealClazz::name::set)
// -- 属性 --
val rAgeProperty by RealClazz::age.delegator(realClazz)
var rNameProperty by RealClazz::name.delegator(realClazz)
// -- 方法 --
val rScoreGetter by RealClazz::getScore.delegator(realClazz)
var rScoreSetter by RealClazz::setScore.delegator(realClazz)
// --- 有接收者,懒汉式代理 ------------------------------------------
val rAgeLazy by delegateLazyOf(RealClazz::age::get) { realClazz }
var rNameSetterLazy by delegateLazyOf(RealClazz::name::set) { realClazz }
var rNameLazy by delegateLazyOf(RealClazz::name::get, RealClazz::name::set) { realClazz }
// -- 属性 --
val rAgePropertyLazy by RealClazz::age.delegatorLazy { realClazz }
var rNamePropertyLazy by RealClazz::name.delegatorLazy { realClazz }
// -- 方法 --
val rScoreGetterLazy by RealClazz::getScore.delegatorLazy { realClazz }
var rScoreSetterLazy by RealClazz::setScore.delegatorLazy { realClazz }
}
fun main() {
// --- 无接收者,饿汉式代理 ------------------------------------------
Person.age.also { println("(age=$it)") } // (age=18)
Person.nameSetter = "张三"
Person.printlnRealClazz() //[name=张三, age=18, score=0]
Person.name = "小六子"
Person.name.also(::println) // 小六子
// -- 属性 --
Person.ageProperty.apply(::println) // 18
Person.nameProperty = "李四"
Person.nameProperty.apply(::println) // 李四
// -- 方法 --
Person.scoreSetter = 21
Person.scoreGetter.apply(::println) // 21
Person.printlnRealClazz() //[name=李四, age=18, score=21]
println("======================================================")
// --- 有接收者,饿汉式代理 ------------------------------------------
Person.rAge.also { println("(age=$it)") } // (age=18)
Person.rNameSetter = "张三"
Person.printlnRealClazz() //[name=张三, age=18, score=21]
Person.rName = "小六子"
Person.rName.also(::println) // 小六子
// -- 属性 --
Person.rAgeProperty.apply(::println) // 18
Person.rNameProperty = "李四"
Person.rNameProperty.apply(::println) // 李四
// -- 方法 --
Person.rScoreSetter = 42
Person.rScoreGetter.apply(::println) // 42
Person.printlnRealClazz() //[name=李四, age=18, score=42]
println("======================================================")
// --- 有接收者,懒汉式代理 ------------------------------------------
Person.rAgeLazy.also { println("(age=$it)") } // (age=18)
Person.rNameSetterLazy = "张三"
Person.printlnRealClazz() //[name=张三, age=18, score=42]
Person.rNameLazy = "小六子"
Person.rNameLazy.also(::println) // 小六子
// -- 属性 --
Person.rAgePropertyLazy.apply(::println) // 18
Person.rNamePropertyLazy = "李四"
Person.rNamePropertyLazy.apply(::println) // 李四
// -- 方法 --
Person.rScoreSetterLazy = 84
Person.rScoreGetterLazy.apply(::println) // 84
Person.printlnRealClazz() //[name=李四, age=18, score=84]
// 特殊情况测试,由于我们提供了只有setter的情况,而这中情况只能用var接收,
// 这就导致此属性代理getter情况可能被执行,如果无调用编译时应抛出异常。
try {
val name = Person.nameSetter
} catch (e: Exception) {
e.printStackTrace()
println("======================================================")
}
try {
val name = Person.rNameSetter
} catch (e: Exception) {
e.printStackTrace()
println("======================================================")
}
try {
val name = Person.rNameSetterLazy
} catch (e: Exception) {
e.printStackTrace()
}
}
运行结果:
(age=18)
[name=张三, age=18, score=0]
小六子
18
李四
21
[name=李四, age=18, score=21]
======================================================
(age=18)
[name=张三, age=18, score=21]
小六子
18
李四
42
[name=李四, age=18, score=42]
======================================================
(age=18)
[name=张三, age=18, score=42]
小六子
18
李四
84
[name=李四, age=18, score=84]
java.lang.NoSuchMethodException: The value of nameSetter can't be get!
at com.lak.app.util.WriteOnlyProperty.getValue(Delegates.kt:138)
at com.lak.app.test.Person.getNameSetter(Delegates.kt)
at com.lak.app.test.DelegatesKt.main(Delegates.kt:104)
at com.lak.app.test.DelegatesKt.main(Delegates.kt)
java.lang.NoSuchMethodException: The value of rNameSetter can't be get!
======================================================
at com.lak.app.util.WriteOnlyProperty.getValue(Delegates.kt:138)
at com.lak.app.test.Person.getRNameSetter(Delegates.kt)
at com.lak.app.test.DelegatesKt.main(Delegates.kt:110)
at com.lak.app.test.DelegatesKt.main(Delegates.kt)
======================================================
java.lang.NoSuchMethodException: The value of rNameSetterLazy can't be get!
at com.lak.app.util.WriteOnlyProperty.getValue(Delegates.kt:138)
at com.lak.app.test.Person.getRNameSetterLazy(Delegates.kt)
at com.lak.app.test.DelegatesKt.main(Delegates.kt:116)
at com.lak.app.test.DelegatesKt.main(Delegates.kt)
网友评论