You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.25 15:24:03