Application单例化和属性的Delegated - 怎么去创建一个自定义的委托

优质
小牛编辑
127浏览
2023-12-01

先来说说我们要实现什么,举个例子,我们创建一个notNull的委托,它只能被赋值一次,如果第二次赋值,它就会抛异常。

Kotlin库提供了几个接口,我们自己的委托必须要实现:ReadOnlyPropertyReadWriteProperty。具体取决于我们被委托的对象是val还是var

我们要做的第一件事就是创建一个类然后继承ReadWriteProperty

  1. private class NotNullSingleValueVar<T>() : ReadWriteProperty<Any?, T> {
  2. override fun getValue(thisRef: Any?, property: KProperty<*>): T {
  3. throw UnsupportedOperationException()
  4. }
  5. override fun setValue(thisRef: Any?, property: KProperty<*>, value: T) {
  6. }
  7. }

这个委托可以作用在任何非null的类型。它接收任何类型的引用,然后像getter和setter那样使用T。现在我们需要去实现这些函数。

  • Getter函数 如果已经被初始化,则会返回一个值,否则会抛异常。
  • Setter函数 如果仍然是null,则赋值,否则会抛异常。
  1. private class NotNullSingleValueVar<T>() : ReadWriteProperty<Any?, T> {
  2. private var value: T? = null
  3. override fun getValue(thisRef: Any?, property: KProperty<*>): T {
  4. return value ?: throw IllegalStateException("${desc.name} " +
  5. "not initialized")
  6. }
  7. override fun setValue(thisRef: Any?, property: KProperty<*>, value: T) {
  8. this.value = if (this.value == null) value
  9. else throw IllegalStateException("${desc.name} already initialized")
  10. }
  11. }

现在你可以创建一个对象,然后添加函数使用你的委托:

  1. object DelegatesExt {
  2. fun notNullSingleValue<T>():
  3. ReadWriteProperty<Any?, T> = NotNullSingleValueVar()
  4. }