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

从Redis反序列化泛型列表时返回LinkedHashMap问题排查

问题描述

我有如下一段Kotlin代码:

val objs = results.map {
    if(it == null) return@map null
    val typeRef: TypeReference<T> = object : TypeReference<T>() {}
    jacksonObjectMapper().readValue(it, typeRef)
}

我希望该方法返回泛型类型T的可空列表List<T?>,其中T是方法签名中的泛型参数。虽然代码能运行,但未达到预期效果:当调用myMethod<MyDTO>(keys: List<String>)时,返回的是LinkedHashMap列表而非预期的MyDTO列表。请问我哪里出错了?

问题原因

这是泛型类型擦除导致的问题。JVM运行时会抹掉泛型参数T的具体类型信息,你创建的TypeReference<T>其实根本不知道T是MyDTO,Jackson没法把数据反序列化成MyDTO对象,只能默认用LinkedHashMap存储JSON的键值对。

解决方案

1. 让方法接收TypeReference<T>作为参数

直接让调用方传入包含具体类型信息的TypeReference,这样Jackson就能明确知道要转成什么类型:

fun <T> myMethod(keys: List<String>, typeRef: TypeReference<T>): List<T?> {
    val results = // 这里写获取原始数据的逻辑
    return results.map {
        if (it == null) null
        else jacksonObjectMapper().readValue(it, typeRef)
    }
}

// 调用示例
val result = myMethod(listOf("key1"), object : TypeReference<MyDTO>() {})

2. 用KClass结合TypeFactory生成类型信息

如果不想让调用方传TypeReference,可以用Kotlin的KClass来构建准确的类型信息:

fun <T : Any> myMethod(keys: List<String>, clazz: KClass<T>): List<T?> {
    val results = // 这里写获取原始数据的逻辑
    val targetType = jacksonObjectMapper().typeFactory.constructType(clazz.java)
    return results.map {
        if (it == null) null
        else jacksonObjectMapper().readValue(it, targetType)
    }
}

// 调用示例
val result = myMethod(listOf("key1"), MyDTO::class)

3. 利用reified泛型(仅限inline函数)

如果方法可以定义为inline函数,用reified关键字就能保留泛型的具体类型信息,不用额外传参数:

inline fun <reified T : Any> myMethod(keys: List<String>): List<T?> {
    val results = // 这里写获取原始数据的逻辑
    return results.map {
        if (it == null) null
        else jacksonObjectMapper().readValue(it, object : TypeReference<T>() {})
    }
}

// 调用示例
val result = myMethod<MyDTO>(listOf("key1"))

这里因为reified保留了T的具体类型,TypeReference<T>能正确识别出MyDTO,Jackson就能正常完成反序列化。

内容的提问来源于stack exchange,提问作者Matias Barrios

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.24 11:55:25