Better

业精于勤荒于嬉

Idiomatic kotlin:property delegates

Better's Avatar 2019-06-02 Kotlin

  1. 1. lazy
  2. 2. notnull
  3. 3. observable
  4. 4. 参考

kotlin 中的属性类型有两种变量和常量

  • 变量varval。kotlin 中变量是默认有getter()setter()方法,以及backing field
  • 常量 const val。常量是没有getter()setter()
1
2
3
4
5
6
7
8
var name: String? = null
set(value) {
field = value
}
get() {
return field
}
const val DAVID = "david"

backing field 相当于是一个语法糖,属性自动生成了setter()getter() ,并不能在方法内部直接访问属性,不然就无限递归了,所以只能通过其他的方式访问。backing field跟属性是一一对应的,访问或这是它的值应对到对应的属性上了。

属性的代理是将属性委托给另外的属性来处理,主要是setter()getter()。而类的代理,是将类中的方法实现委托给另一个也实现了这个方法的对象类处理。
常见的属性代理有

  • 延时初始化lateinit,by lazy{}
  • 非空校验by Delegates.notNull<T>()
  • obserable 类观察属性值的变化by Delegates.observable(),by Delegates.vetoable()
  • 自定义代理ReadWritePorperty,ReadOnlyProperty

lazy

1
2
val name1: String by lazy { "god" }
lateinit var name2: String

bummock

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
@NotNull
private static final Lazy name1$delegate;
@NotNull
public static String name2;

static {
name1$delegate = LazyKt.lazy((Function0)null.INSTANCE);
}

@NotNull
public static final String getName1() {
Lazy var0 = name1$delegate;
Object var1 = null;
KProperty var2 = $$delegatedProperties[0];
boolean var3 = false;
return (String)var0.getValue();
}

@NotNull
public static final String getName2() {
String var10000 = name2;
if (var10000 == null) {
Intrinsics.throwUninitializedPropertyAccessException("name2");
}

return var10000;
}

public static final void setName2(@NotNull String var0) {
Intrinsics.checkParameterIsNotNull(var0, "<set-?>");
name2 = var0;
}

lateinit只是做了下判断,为空的时候抛异常。 lazy使用到属性代理

notnull

1
var name3: String by Delegates.notNull()
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
@NotNull
private static final ReadWriteProperty name3$delegate;

static {
name3$delegate = Delegates.INSTANCE.notNull();
}

@NotNull
public static final String getName3() {
return (String)name3$delegate.getValue((Object)null, $$delegatedProperties[1]);
}

public static final void setName3(@NotNull String var0) {
Intrinsics.checkParameterIsNotNull(var0, "<set-?>");
name3$delegate.setValue((Object)null, $$delegatedProperties[1], var0);
}

observable

observable监听值得变化。vetoable()监听值得变化,并作出应对,是否真正得修改值。

1
2
3
4
5
6
7
var name4: String by Delegates.observable("<Initial Value>") { property, oldValue, newValue ->
println("Property ${property.name} changed value from $oldValue to $newValue")
}
var name5: Int by Delegates.vetoable(0) { property, oldValue, newValue ->
println("${property.name} $oldValue -> $newValue")
newValue % 2 == 0
}

参考

kotlinDoc-Properties
Idiomatic Kotlin:property delegate
functional_kotlin

This article was last updated on days ago, and the information described in the article may have changed.