Kotlin 属性委托 observable 的实现原理
Kotlin 的 Delegates.observable
是 Kotlin 标准库中提供的一个属性委托,它允许你在属性的值发生变化时自动执行某段逻辑,比如常用于监听属性变化(例如 UI 数据更新)。
基本使用示例:
import kotlin.properties.Delegatesvar name: String by Delegates.observable("initial") { property, oldValue, newValue ->println("${property.name} changed from $oldValue to $newValue")
}fun main() {name = "Alice"name = "Bob"
}
输出:
name changed from initial to Alice
name changed from Alice to Bob
实现原理
1. Delegates.observable(...)
返回了一个实现了 ReadWriteProperty
接口的对象:
public inline fun <T> observable(initialValue: T, crossinline onChange: (property: KProperty<*>, oldValue: T, newValue: T) -> Unit):ReadWriteProperty<Any?, T> =object : ObservableProperty<T>(initialValue) {override fun afterChange(property: KProperty<*>, oldValue: T, newValue: T) = onChange(property, oldValue, newValue)}
它返回了一个 ObservableProperty
实例。
2. ObservableProperty
实现了属性委托接口ReadWriteProperty
:
public abstract class ObservableProperty<V>(initialValue: V) : ReadWriteProperty<Any?, V> {private var value = initialValueprotected open fun beforeChange(property: KProperty<*>, oldValue: V, newValue: V): Boolean = trueprotected open fun afterChange(property: KProperty<*>, oldValue: V, newValue: V): Unit {}public override fun getValue(thisRef: Any?, property: KProperty<*>): V {return value}public override fun setValue(thisRef: Any?, property: KProperty<*>, value: V) {val oldValue = this.valueif (!beforeChange(property, oldValue, value)) {return}this.value = valueafterChange(property, oldValue, value)}override fun toString(): String = "ObservableProperty(value=$value)"
}
beforeChange
在属性值被变更前被调用,默认返回true
,就是说即使你写出这样的代码:
import kotlin.properties.Delegatesvar name: String by Delegates.observable("init") { property, oldValue, newValue ->println("${property.name} changed from $oldValue to $newValue")
}fun main() {name = "init"name = "Bob"
}
也会输出结果:
name changed from init to init
name changed from init to Bob
ObservableProperty
内部维护了属性值,并在 setValue
方法中触发回调,这个回调的实现就是我们传入的lambda
参数onChange
。
每次我们通过赋值等操作修改被委托的属性时,都会触发 setValue()
方法,从而调用 onChange
回调。
总结:工作机制
Delegates.observable(initialValue, onChange)
返回ObservableProperty
实例ObservableProperty
实现了ReadWriteProperty
接口Kotlin
编译器在by
后会将属性访问转发给getValue()
和setValue()
setValue()
中自动触发onChange()
回调
使用场景
- 数据绑定(如 UI)
- 表单输入监听
- MVVM 架构中
ViewModel
属性监听 - 日志审计、调试属性变化等