kotlin的属性代理


今天学习了一下kotlin的属性代理,觉的挺有趣的,借助属性代理我们可以实现一些有意思的功能。

基本语法

class Student{
    
    
    var name: String by Delegate()
}

class Delegate{
    
    
    operator fun <T> getValue(thisRef: Any?, property: KProperty<*>): T{
    
    
        ...
    }
    operator fun <T> setValue(thisRef: Any?, property: KProperty<*>, value: T){
    
    
        ...
    }
}

案例一:利用属性代理实现json字段的获取

class JsonDelegate(jsonStr: String) {
    
    

    val jsonObject: JSONObject = JSONObject(jsonStr)

    public fun <T> delegate(defaultValue: T, key: String = ""): Delegate<T> {
    
    
        return Delegate(jsonObject, key, defaultValue)
    }

    public override fun toString(): String {
    
    
        return jsonObject.toString()
    }

    class Delegate<T>(
        var jsonObject: JSONObject,
        var key: String,
        val defaultValue: T
    ) {
    
    

        operator fun setValue(thisRef: Any?, property: KProperty<*>, value: T) {
    
    
            val key = getKey(property)
            jsonObject.put(key, value)
        }

        protected fun getKey(property: KProperty<*>): String {
    
    
            if (!key.isEmpty()) {
    
    
                return key
            }
            return property.name
        }

        operator fun getValue(thisRef: Any?, property: KProperty<*>): T {
    
    
            val key = getKey(property)
            if (jsonObject.has(key)) {
    
    
                val value = jsonObject.get(getKey(property))
                return value as T
            } else {
    
    
                return defaultValue
            }
        }
    }

}

使用方式:

val jsonDelegate = JsonDelegate(jsonStr)
val value1 by jsonDelegate.delegate(-1,"test")//第一个参数是默认值,第二个参数是key
val value2 by jsonDelegate.delegate(-2)//若没有第二个参数,则key为变量名

这样我们在从一段json当中取值时,就不用每次都判断json是否存在这个key,若不存在这个key,则直接返回传入的默认值。

案例二:利用属性代理实现SharedPreferences取值和存储

class SPDelegate(tag: String, context: Context) {
    
    
    val sp:SharedPreferences by lazy {
    
    
        context.applicationContext.getSharedPreferences(tag,Context.MODE_PRIVATE)
    }

    public fun <T> delegate(defaultValue: T, key: String = ""): Delegate<T> {
    
    
        return Delegate(sp,key,defaultValue)
    }

    class Delegate<T>(
        val sp:SharedPreferences,
        var key: String,
        val defaultValue: T
    ) {
    
    

        operator fun setValue(thisRef: Any?, property: KProperty<*>, value: T) {
    
    
            val key = getKey(property)
            with(sp.edit()) {
    
    
                when (value) {
    
    
                    is String -> putString(key, value)
                    is Int -> putInt(key, value)
                    is Float -> putFloat(key, value)
                    is Long -> putLong(key, value)
                    is Boolean -> putBoolean(key, value)
                    else -> throw IllegalArgumentException("Unsupported type.")
                }
            }.apply()
        }

        protected fun getKey(property: KProperty<*>): String {
    
    
            if (!key.isEmpty()) {
    
    
                return key
            }
            return property.name
        }

        operator fun getValue(thisRef: Any?, property: KProperty<*>): T {
    
    
            val result =  when (defaultValue) {
    
    
                is String -> sp.getString(getKey(property), defaultValue as String) ?: defaultValue
                is Int -> sp.getInt(getKey(property), defaultValue as Int)
                is Float -> sp.getFloat(getKey(property), defaultValue as Float)
                is Long -> sp.getLong(getKey(property), defaultValue as Long)
                is Boolean -> sp.getBoolean(getKey(property), defaultValue as Boolean)
                else -> throw IllegalArgumentException("Unsupported type.")
            }
            return result as T
        }
    }
}

使用方式:

val delegate = SPDelegate("MainActivity",this)
var test by delegate.delegate(1,"tttt")//第一个参数表示默认值,第二个参数表示key
var test1 by delegate.delegate("test")//若只有一个参数,则key为变量名称

这样我们就可以避免写出大段的SharedPreferences代码,我们的代码也非常的简洁。

猜你喜欢

转载自blog.csdn.net/hbdatouerzi/article/details/123218366