普通的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, "" );
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, "" );
this.delegateProperty2$delegate.setValue(this, $$delegatedProperties[1], var1);
}
}
比如我们需要实现对用户中心相关属性赋值时候的一些过滤:
/**
* 创建对应模式下的过滤委派
*/
//提供指定限定词的方式进行过滤
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
}
}
}
//用户ID
private 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
}