普通的delegate代理属性get/set方法,可以看到类中会声明一个数组保存需要代理的所有KProperty字段信息(包含类名,字段名称,字段签名())
PS:冷知识map也可以用于委托,只要有get/set方法就可以用作委托,只不过map的key是字段的名称,value才是真正的值,这个有点限制哈哈,但是如果想要自己实现map也可以
public final class TestDelegateProperty {
// $FF: synthetic field
//自动生成的代理属性数组,保存着对应的字段名称及字段的get方法用于定位到对应的代理类中获取get方法
static final KProperty[] $$delegatedProperties = new KProperty[]{(KProperty)Reflection.property1(new PropertyReference1Impl(TestDelegateProperty.class, "delegateProperty", "getDelegateProperty()Ljava/lang/String;", 0))};
@NotNull
private final DelegatePropertyClass delegateProperty$delegate = new DelegatePropertyClass();@NotNull
public final String getDelegateProperty() {
return this.delegateProperty$delegate.getValue(this, $$delegatedProperties[0]);
}
}
如果有多个代理属性呢?也很简单,无非就是代理属性数组中再多几个元素和对应的代理实例:
public final class TestDelegateProperty {
// $FF: synthetic field
static final KProperty[] $$delegatedProperties = new KProperty[]{(KProperty)Reflection.mutableProperty1(new MutablePropertyReference1Impl(TestDelegateProperty.class, "delegateProperty", "getDelegateProperty()Ljava/lang/String;", 0)), (KProperty)Reflection.mutableProperty1(new MutablePropertyReference1Impl(TestDelegateProperty.class, "delegateProperty2", "getDelegateProperty2()Ljava/lang/String;", 0))};
@NotNull
private final DelegatePropertyClass delegateProperty$delegate = new DelegatePropertyClass();
@NotNull
private final DelegatePropertyClass delegateProperty2$delegate = new DelegatePropertyClass();@NotNull
public final String getDelegateProperty() {
return this.delegateProperty$delegate.getValue(this, $$delegatedProperties[0]);
}public final void setDelegateProperty(@NotNull String var1) {
Intrinsics.checkNotNullParameter(var1, "<set-?>");
this.delegateProperty$delegate.setValue(this, $$delegatedProperties[0], var1);
}@NotNull
public final String getDelegateProperty2() {
return this.delegateProperty2$delegate.getValue(this, $$delegatedProperties[1]);
}public final void setDelegateProperty2(@NotNull String var1) {
Intrinsics.checkNotNullParameter(var1, "<set-?>");
this.delegateProperty2$delegate.setValue(this, $$delegatedProperties[1], var1);
}
}
案例:为用户中心相关的属性进行代理过滤
比如我们需要实现对用户中心相关属性赋值时候的一些过滤:
用户属性代理KT文件
/*** 创建对应模式下的过滤委派*/
//提供指定限定词的方式进行过滤
fun userDelegateByFiled(filterField: String) =UserPropertyDelegateByField(filterField)//提供块体的方式进行过滤
fun userDelegateByFunc(filterFunc: (String) -> Boolean) =UserPropertyDelegateByFunc(filterFunc)/*** 提供指定限定词的方式进行过滤*/
class UserPropertyDelegateByField(private val filterField: String) {private var userCenterProperty = ""/*** @param thisRef:thisRef代表的是属性所属的类* @param property:KProperty类实例,代表的是kotlin的属性拥有字段名称,字段所属的类,字段get/set的对应方法签名*/operator fun <T> getValue(thisRef: T, property: KProperty<*>): String {return userCenterProperty}/*** 对于用户体系的属性进行过滤* @param thisRef:thisRef代表的是属性所属的类* @param property:KProperty类实例,代表的是kotlin的属性拥有字段名称,字段所属的类,字段get/set的对应方法签名* @param value 传入的对应值*/operator fun <T> setValue(thisRef: T, property: KProperty<*>, value: String) {if (!value.contains(filterField)) {userCenterProperty = value}}
}/*** 提供块体的方式进行过滤*/
class UserPropertyDelegateByFunc(private val filterFunc: (String) -> Boolean) {private var userCenterProperty = ""/*** @param thisRef:thisRef代表的是属性所属的类* @param property:KProperty类实例,代表的是kotlin的属性拥有字段名称,字段所属的类,字段get/set的对应方法签名*/operator fun <T> getValue(thisRef: T, property: KProperty<*>): String {return userCenterProperty}/*** 对于用户体系的属性进行过滤* @param thisRef:thisRef代表的是属性所属的类* @param property:KProperty类实例,代表的是kotlin的属性拥有字段名称,字段所属的类,字段get/set的对应方法签名* @param value 传入的对应值*/operator fun <T> setValue(thisRef: T, property: KProperty<*>, value: String) {if (filterFunc(value)) {userCenterProperty = value}}
}
使用代码
//用户IDprivate var userCenterId by userDelegateByFiled("defaultUser")//用户生日private var userCenterBirthday by userDelegateByFunc(::userBirthdayFilterFunc)//用户生日信息赋值过滤private fun userBirthdayFilterFunc(birthday: String): Boolean {if (birthday.contains("default")) {return false}return true}