2019-07-26:什么是委托属性?请简要说说其使用场景和原理?
Moosphan opened this issue · 6 comments
Moosphan commented
2019-07-26:什么是委托属性?请简要说说其使用场景和原理?
18361237136 commented
把一件事委托给其他人来做。如kotlin中的by
var p: String by Delegate(),get和set委托给Delegate的getValue()方法和setValue()方法
yizems commented
居然没人说,很奇怪呀=.=
- by lazy: 用于 延迟初始化
- 自定义委托,不如我想获取一个 用户id,那么他是在 本地数据库中的,那么我就可以
private val userId by UserIdDelegete()
UserIdDelegete中 定义了 user id 的获取和设置方法
写的不一定对哈,用的不多,也记不住
- butterknife好像有个kotlin 版本的 ,用于id查找,可以参考,很优秀
原理的话不太好写,但是可以借助于 kotlin byteCode 工具来看自动生成的代码,类委托的话大家自己百度吧,简单对比一下属性委托
//源文件
class A {
private var name by Delegate()
}
class Delegate {
operator fun getValue(thisRef: Any?, property: KProperty<*>): String {
return "$thisRef, 这里委托了 ${property.name} 属性"
}
operator fun setValue(thisRef: Any?, property: KProperty<*>, value: String) {
println("$thisRef 的 ${property.name} 属性赋值为 $value")
}
}
ByteCode 工具decompile的java文件
public final class Delegate {
@NotNull
public final String getValue(@Nullable Object thisRef, @NotNull KProperty property) {
//将属性传递过来,如果只有一个,直接写获取的逻辑就好
Intrinsics.checkParameterIsNotNull(property, "property");
return thisRef + ", 这里委托了 " + property.getName() + " 属性";
}
public final void setValue(@Nullable Object thisRef, @NotNull KProperty property, @NotNull String value) {
Intrinsics.checkParameterIsNotNull(property, "property");
Intrinsics.checkParameterIsNotNull(value, "value");
String var4 = thisRef + " 的 " + property.getName() + " 属性赋值为 " + value;
System.out.println(var4);
}
}
public final class A {
// $FF: synthetic field
//虽然实际上我也不知道这个是啥意思,但是能大概猜出来啥意思,用于反射和属性定义,毕竟这个类实际上是没有 name:String 属性的
static final KProperty[] $$delegatedProperties = new KProperty[]{(KProperty)Reflection.mutableProperty1(new MutablePropertyReference1Impl(Reflection.getOrCreateKotlinClass(A.class), "name", "getName()Ljava/lang/String;"))};
//真正的类型是 Delegate的类型
private final Delegate name$delegate = new Delegate();
// get set 方法 是 String 类型
private final String getName() {
//调用委托的 getValue 方法
return this.name$delegate.getValue(this, $$delegatedProperties[0]);
}
private final void setName(String var1) {
this.name$delegate.setValue(this, $$delegatedProperties[0], var1);
}
}
MicroKibaco commented
属性委托
有些常见的属性操作,我们可以通过委托方式,让它实现,例如:
- lazy 延迟属性: 值只在第一次访问的时候计算
- observable 可观察属性:属性发生改变时通知
- map 集合: 将属性存在一个map集合里面
类委托
可以通过类委托来减少 extend
类委托的时,编译器回优使用自身重新函数,而不是委托对象的函数
interface Base{
fun print()
}
case BaseImpl(var x: Int):Base{
override fun print(){
print(x)
}
}
// Derived 的 print 实现会通过构造函数的b对象来完成
class Derived(b: base): Base by b
lix-b commented
类委托: class A: Base by BaseImp() 实现一个接口了正好有一个类可以使用
属性委托:委托的类需要实现 getValue和setValue 函数加上operator关键字
委托延迟: by lazy ,lazy内只执行一次,后续只返回结果
委托工厂:主要需要实现ReadWriteProperty 接口
属性监听: Delegates.observable 无条件赋值 和Delegates.vetoable (有条件的赋值)
MicroKibaco commented
这是来自QQ邮箱的假期自动回复邮件。
您好,我最近正在休假中,无法亲自回复您的邮件。我将在假期结束后,尽快给您回复。