泛型扩展函数设计

基于JceStruct的泛型扩展函数设计

1. 基础设计

首先,我们假设JceStruct是后端序列化基类,所有响应数据都继承它。我将设计一个泛型扩展函数系统,支持动态反射将数据结构JSON化。

kotlin 复制代码
// 假设的JceStruct基类
abstract class JceStruct {
    // 假设JceStruct有一些基本属性和方法
}

// 示例数据类
class UserInfo : JceStruct() {
    var userId: String = ""
    var userName: String = ""
    var age: Int = 0
    var profile: UserProfile? = null
    var friends: List<UserInfo> = emptyList()
}

class UserProfile : JceStruct() {
    var avatar: String = ""
    var bio: String = ""
    var tags: List<String> = emptyList()
}

2. 核心扩展函数设计

2.1 基础JSON化扩展函数

kotlin 复制代码
/**
 * 将JceStruct及其子类转换为JSON字符串
 * 支持嵌套对象和列表
 */
fun <T : JceStruct> T.toJsonString(
    prettyPrint: Boolean = false,
    excludeNullValues: Boolean = true
): String {
    return toJson(excludeNullValues).toString(prettyPrint)
}

/**
 * 将JceStruct及其子类转换为JSONObject
 */
fun <T : JceStruct> T.toJson(excludeNullValues: Boolean = true): JSONObject {
    val jsonObject = JSONObject()
    
    // 使用反射获取所有属性
    this::class.members
        .filterIsInstance<KProperty1<Any, *>>()
        .forEach { property ->
            try {
                val value = property.get(this)
                val propertyName = property.name
                
                // 根据excludeNullValues决定是否排除null值
                if (!excludeNullValues || value != null) {
                    when (value) {
                        is JceStruct -> {
                            // 递归处理嵌套的JceStruct对象
                            jsonObject.put(propertyName, value.toJson(excludeNullValues))
                        }
                        is List<*> -> {
                            // 处理列表
                            val jsonArray = JSONArray()
                            value.forEach { item ->
                                when (item) {
                                    is JceStruct -> jsonArray.put(item.toJson(excludeNullValues))
                                    else -> jsonArray.put(item)
                                }
                            }
                            jsonObject.put(propertyName, jsonArray)
                        }
                        is Map<*, *> -> {
                            // 处理Map
                            val jsonMap = JSONObject()
                            value.forEach { (key, mapValue) ->
                                when (mapValue) {
                                    is JceStruct -> jsonMap.put(key.toString(), mapValue.toJson(excludeNullValues))
                                    else -> jsonMap.put(key.toString(), mapValue)
                                }
                            }
                            jsonObject.put(propertyName, jsonMap)
                        }
                        else -> {
                            // 处理基本类型
                            jsonObject.put(propertyName, value)
                        }
                    }
                }
            } catch (e: Exception) {
                // 忽略无法访问的属性
                KLog.w("JceStructExtension", "Failed to serialize property: ${property.name}", e)
            }
        }
    
    return jsonObject
}

2.2 高级扩展函数

kotlin 复制代码
/**
 * 将JceStruct转换为Map
 */
fun <T : JceStruct> T.toMap(
    excludeNullValues: Boolean = true,
    deep: Boolean = true
): Map<String, Any?> {
    return if (deep) {
        toJson(excludeNullValues).toMap()
    } else {
        val map = mutableMapOf<String, Any?>()
        
        this::class.members
            .filterIsInstance<KProperty1<Any, *>>()
            .forEach { property ->
                try {
                    val value = property.get(this)
                    if (!excludeNullValues || value != null) {
                        map[property.name] = value
                    }
                } catch (e: Exception) {
                    KLog.w("JceStructExtension", "Failed to get property: ${property.name}", e)
                }
            }
        
        map
    }
}

/**
 * 将JceStruct转换为特定类型的Map
 */
inline fun <reified K, reified V> <T : JceStruct> T.toTypedMap(
    excludeNullValues: Boolean = true,
    keyTransform: (String) -> K = { it as K },
    valueTransform: (Any?) -> V = { it as V }
): Map<K, V> {
    return toMap(excludeNullValues).mapKeys { (key, _) -> keyTransform(key) }
        .mapValues { (_, value) -> valueTransform(value) }
}

/**
 * 从JSON字符串创建JceStruct实例
 */
inline fun <reified T : JceStruct> String.toJceStruct(): T? {
    return try {
        val jsonObject = JSONObject(this)
        jsonObject.toJceStruct<T>()
    } catch (e: Exception) {
        KLog.e("JceStructExtension", "Failed to parse JSON to JceStruct", e)
        null
    }
}

/**
 * 从JSONObject创建JceStruct实例
 */
inline fun <reified T : JceStruct> JSONObject.toJceStruct(): T? {
    return try {
        val instance = T::class.createInstance()
        
        this.keys().forEach { key ->
            val value = this.opt(key)
            val property = T::class.members
                .filterIsInstance<KMutableProperty1<Any, *>>()
                .find { it.name == key }
            
            property?.let {
                try {
                    when (val propValue = value) {
                        is JSONObject -> {
                            // 处理嵌套对象
                            val nestedValue = propValue.toJceStruct<JceStruct>()
                            it.setter.call(instance, nestedValue)
                        }
                        is JSONArray -> {
                            // 处理数组
                            val list = mutableListOf<Any?>()
                            for (i in 0 until propValue.length()) {
                                val item = propValue.opt(i)
                                when (item) {
                                    is JSONObject -> {
                                        val nestedItem = item.toJceStruct<JceStruct>()
                                        list.add(nestedItem)
                                    }
                                    else -> list.add(item)
                                }
                            }
                            it.setter.call(instance, list)
                        }
                        else -> {
                            it.setter.call(instance, propValue)
                        }
                    }
                } catch (e: Exception) {
                    KLog.w("JceStructExtension", "Failed to set property: $key", e)
                }
            }
        }
        
        instance
    } catch (e: Exception) {
        KLog.e("JceStructExtension", "Failed to create JceStruct from JSON", e)
        null
    }
}

3. 集合扩展函数

kotlin 复制代码
/**
 * 将JceStruct列表转换为JSON数组字符串
 */
fun <T : JceStruct> List<T>.toJsonString(
    prettyPrint: Boolean = false,
    excludeNullValues: Boolean = true
): String {
    val jsonArray = JSONArray()
    this.forEach { item ->
        jsonArray.put(item.toJson(excludeNullValues))
    }
    return if (prettyPrint) {
        jsonArray.toString(2)
    } else {
        jsonArray.toString()
    }
}

/**
 * 将JceStruct列表转换为JSONArray
 */
fun <T : JceStruct> List<T>.toJsonArray(excludeNullValues: Boolean = true): JSONArray {
    val jsonArray = JSONArray()
    this.forEach { item ->
        jsonArray.put(item.toJson(excludeNullValues))
    }
    return jsonArray
}

/**
 * 从JSON数组字符串创建JceStruct列表
 */
inline fun <reified T : JceStruct> String.toJceStructList(): List<T> {
    return try {
        val jsonArray = JSONArray(this)
        jsonArray.toJceStructList<T>()
    } catch (e: Exception) {
        KLog.e("JceStructExtension", "Failed to parse JSON array to JceStruct list", e)
        emptyList()
    }
}

/**
 * 从JSONArray创建JceStruct列表
 */
inline fun <reified T : JceStruct> JSONArray.toJceStructList(): List<T> {
    val list = mutableListOf<T>()
    for (i in 0 until this.length()) {
        val item = this.opt(i)
        when (item) {
            is JSONObject -> {
                val jceStruct = item.toJceStruct<T>()
                jceStruct?.let { list.add(it) }
            }
            else -> KLog.w("JceStructExtension", "Item at index $i is not a JSONObject")
        }
    }
    return list
}

4. 高级功能扩展

kotlin 复制代码
/**
 * 比较两个JceStruct对象的差异
 */
fun <T : JceStruct> T.diffWith(other: T): JSONObject {
    val diff = JSONObject()
    
    this::class.members
        .filterIsInstance<KProperty1<Any, *>>()
        .forEach { property ->
            try {
                val thisValue = property.get(this)
                val otherValue = property.get(other)
                
                if (thisValue != otherValue) {
                    val propertyDiff = JSONObject()
                    propertyDiff.put("old", thisValue)
                    propertyDiff.put("new", otherValue)
                    diff.put(property.name, propertyDiff)
                }
            } catch (e: Exception) {
                KLog.w("JceStructExtension", "Failed to compare property: ${property.name}", e)
            }
        }
    
    return diff
}

/**
 * 合并两个JceStruct对象
 */
fun <T : JceStruct> T.mergeWith(other: T, overwrite: Boolean = true): T {
    try {
        val result = this::class.createInstance()
        
        this::class.members
            .filterIsInstance<KMutableProperty1<Any, *>>()
            .forEach { property ->
                try {
                    val thisValue = property.get(this)
                    val otherValue = property.get(other)
                    
                    when {
                        otherValue != null && overwrite -> {
                            property.setter.call(result, otherValue)
                        }
                        thisValue != null -> {
                            property.setter.call(result, thisValue)
                        }
                        otherValue != null -> {
                            property.setter.call(result, otherValue)
                        }
                    }
                } catch (e: Exception) {
                    KLog.w("JceStructExtension", "Failed to merge property: ${property.name}", e)
                }
            }
        
        @Suppress("UNCHECKED_CAST")
        return result as T
    } catch (e: Exception) {
        KLog.e("JceStructExtension", "Failed to merge JceStruct objects", e)
        return this
    }
}

/**
 * 深度克隆JceStruct对象
 */
fun <T : JceStruct> T.deepClone(): T {
    return this.toJsonString().toJceStruct<T>() ?: this
}

5. 使用示例

kotlin 复制代码
// 创建测试数据
val userProfile = UserProfile().apply {
    avatar = "https://example.com/avatar.jpg"
    bio = "Software Developer"
    tags = listOf("Kotlin", "Android", "iOS")
}

val userInfo = UserInfo().apply {
    userId = "12345"
    userName = "John Doe"
    age = 30
    profile = userProfile
    friends = listOf(
        UserInfo().apply {
            userId = "67890"
            userName = "Jane Smith"
            age = 28
        }
    )
}

// 转换为JSON字符串
val jsonString = userInfo.toJsonString(prettyPrint = true)
println(jsonString)

// 转换为JSONObject
val jsonObject = userInfo.toJson()
println(jsonObject.toString())

// 转换为Map
val map = userInfo.toMap()
println(map)

// 从JSON字符串创建对象
val newUserInfo = jsonString.toJceStruct<UserInfo>()
println(newUserInfo?.userName)

// 处理列表
val userList = listOf(userInfo, newUserInfo ?: userInfo)
val listJsonString = userList.toJsonString(prettyPrint = true)
println(listJsonString)

// 比较差异
val diff = userInfo.diffWith(newUserInfo ?: userInfo)
println(diff.toString())

// 合并对象
val mergedUser = userInfo.mergeWith(newUserInfo ?: userInfo)
println(mergedUser.userName)

// 深度克隆
val clonedUser = userInfo.deepClone()
clonedUser.userName = "Cloned User"
println(userInfo.userName) // 原对象不变
println(clonedUser.userName) // 克隆对象已修改

6. 性能优化考虑

kotlin 复制代码
/**
 * 缓存反射结果以提高性能
 */
object JceStructReflectionCache {
    private val propertyCache = mutableMapOf<KClass<*>, List<KProperty1<Any, *>>>()
    private val mutablePropertyCache = mutableMapOf<KClass<*>, List<KMutableProperty1<Any, *>>>()
    
    fun getProperties(clazz: KClass<*>): List<KProperty1<Any, *>> {
        return propertyCache.getOrPut(clazz) {
            clazz.members.filterIsInstance<KProperty1<Any, *>>()
        }
    }
    
    fun getMutableProperties(clazz: KClass<*>): List<KMutableProperty1<Any, *>> {
        return mutablePropertyCache.getOrPut(clazz) {
            clazz.members.filterIsInstance<KMutableProperty1<Any, *>>()
        }
    }
}

// 使用缓存优化后的toJson方法
fun <T : JceStruct> T.toJsonOptimized(excludeNullValues: Boolean = true): JSONObject {
    val jsonObject = JSONObject()
    
    // 使用缓存的反射结果
    JceStructReflectionCache.getProperties(this::class)
        .forEach { property ->
            try {
                val value = property.get(this)
                val propertyName = property.name
                
                if (!excludeNullValues || value != null) {
                    when (value) {
                        is JceStruct -> {
                            jsonObject.put(propertyName, value.toJsonOptimized(excludeNullValues))
                        }
                        is List<*> -> {
                            val jsonArray = JSONArray()
                            value.forEach { item ->
                                when (item) {
                                    is JceStruct -> jsonArray.put(item.toJsonOptimized(excludeNullValues))
                                    else -> jsonArray.put(item)
                                }
                            }
                            jsonObject.put(propertyName, jsonArray)
                        }
                        else -> {
                            jsonObject.put(propertyName, value)
                        }
                    }
                }
            } catch (e: Exception) {
                KLog.w("JceStructExtension", "Failed to serialize property: ${property.name}", e)
            }
        }
    
    return jsonObject
}

7. 总结

这个设计提供了以下功能:

  1. 基础JSON转换:将JceStruct及其子类转换为JSON字符串和JSONObject
  2. 嵌套支持:自动处理嵌套的JceStruct对象和列表
  3. 反向转换:从JSON字符串和JSONObject创建JceStruct实例
  4. 集合支持:处理JceStruct列表的JSON转换
  5. 高级功能:对象比较、合并、深度克隆等
  6. 性能优化:使用反射缓存提高性能

这种设计充分利用了Kotlin的泛型、扩展函数和反射特性,为JceStruct及其子类提供了强大的JSON序列化和反序列化能力,同时保持了类型安全和易用性。

相关推荐
粟悟饭&龟波功2 小时前
【GitHub热门项目】(2025-11-09)
github
lkbhua莱克瓦243 小时前
Java基础——集合进阶用到的数据结构知识点3
java·数据结构·github·平衡二叉树·avl
CoderJia程序员甲4 小时前
GitHub 热榜项目 - 日榜(2025-11-08)
ai·开源·github·1024程序员节·ai教程
jz_ddk4 小时前
[实战] 卡尔曼滤波原理与实现(GITHUB 优秀库解读)
算法·github·信号处理·kalman filter·卡尔曼滤波
whysqwhw17 小时前
Kotlin泛型位置规律与设计考量
github
whysqwhw19 小时前
KuiklyUI的ViewRef设计
github
snakecy21 小时前
常用命令记录
linux·运维·github
洛卡卡了1 天前
Typora + PicGo + 阿里云 OSS:一套自己的图床方案
github·设计
逛逛GitHub1 天前
本周 6 个最火火火火 GitHub 项目,AI 杀疯了。
github