KT中代理属性的实现及使用案例分析

普通的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);
}
}

案例:为用户中心相关的属性进行代理过滤

比如我们需要实现对用户中心相关属性赋值时候的一些过滤:

用户属性代理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
        }
    }
}

使用代码

//用户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
    }

你可能感兴趣的:(Android,android,kotlin,java)