关于Kotlin扩展属性的想法


#1

Kotlin 的扩展属性是没有幕后字段的,所以 Kotlin 无法给一个类添加一个属性;所以我想是不是可以在外部储存对象和对这个对象添加的属性的映射,在对象被回收时候自动回收被映射的额外属性以达到扩展带有幕后字段的属性的目的。

/**
 * 扩展属性映射表,映射对象和其额外属性表;使用 WeakHashMap,当对象无其他引用时,自动丢弃其额外属性
 */
private val EXTENSIONS by lazy { WeakHashMap<Any, MutableMap<String, Any>>() }

/**
 * 添加属性
 */
fun Any.addField(name: String, value: Any) {
    EXTENSIONS.getOrPut(this) { HashMap() }[name] = value
}

/**
 * 获取属性
 */
@Suppress("UNCHECKED_CAST")
fun <T> Any.getField(name: String): T? {
    return (EXTENSIONS[this]?.get(name)) as? T
}

/**
 * 移除属性
 */
@Suppress("UNCHECKED_CAST")
fun <T> Any.removeField(name: String): T? {
    return (EXTENSIONS[this]?.remove(name)) as? T
}

使用示例

// View 最后一次点击时间
var View.lastClickTime: Long
    get() = getField<Long>("lastClickTime") ?: 0
    set(value) = putField("lastClickTime", value)

#2

思路是可以,但是这里不能用 WeakHashMap,要考虑到重写了 equals 和 hashCode 的情况,找找有没有 identity weak hash map 这种东西吧


#3

有道理


#4

参考

https://github.com/enbandari/ReleasableVar/blob/master/src/main/kotlin/com/bennyhuo/kotlin/rnnv/WeakIdentityMap.java

有些场景可能还要考虑并发问题。


京ICP备16022265号-2 Kotlin China 2017 - 2018