Kotlin中将Any类型转换为List及嵌套Any对象的转换问题咨询
嵌套Any对象转Map的正确处理方案
问题核心原因
你当前的序列化方法利用Gson做中转序列化/反序列化,但是因为目标类型声明为Map<String, Any>,Gson反序列化时只会将顶层结构解析为Map,嵌套的复杂对象虽然本质也是Gson内部实现的Map类型,但因为泛型擦除会被统一识别为Any类型,无法直接作为Map操作。
解决方案
方案1:使用强类型数据类接收(最推荐)
不需要中转Map,直接定义和数据结构匹配的Kotlin数据类,reified泛型会自动完成嵌套结构的类型解析,不存在嵌套对象类型问题:
// 定义和结构匹配的数据类 data class Product( val goodsName: String, val barcode: String ) data class SourceData( val amount: Int, val product: Product ) // 直接转换为强类型对象,嵌套结构会自动解析 val targetData: SourceData = data.convert() // 可直接访问嵌套字段 val goodsName = targetData.product.goodsName
这个方案还能解决你目前遇到的amount从整型被转成Double的问题,强类型下Gson会自动做类型适配。
方案2:必须使用Map接收时,递归规范化嵌套结构
如果业务场景必须用Map<String, Any>存储,只需新增递归方法,将所有嵌套的非基础类型转换为标准Map结构:
fun Map<String, Any?>.normalizeNested(): Map<String, Any?> { return mapValues { (_, value) -> when (value) { is Map<*, *> -> (value as Map<String, Any?>).normalizeNested() is Collection<*> -> value.map { item -> if (item is Map<*, *>) (item as Map<String, Any?>).normalizeNested() else item } else -> value } } } // 调用示例 val detailsAsData: Map<String, Any> = menuDetailMapper.detailAsMap(data) .serializeToMap() .normalizeNested() as Map<String, Any> // 此时嵌套的product可直接强转为Map使用 val product = detailsAsData["product"] as Map<String, Any> val barcode = product["barcode"] as String
补充优化点
如果需要保留数字的原始类型(避免Int转Double),可以在normalize方法中新增数字类型的判断分支:
// 新增到normalize的when分支中 is Number -> { // 原始是整数就返回Int,否则返回Double if (value.toDouble() % 1 == 0.0) value.toInt() else value }
内容的提问来源于stack exchange,提问作者Polaris Nation
相关产品推荐
相关产品推荐

