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

如何使用Gson通过泛型类类型将JSON数组字符串反序列化为对象模型?

问题描述

我写了一个Kotlin泛型函数,通过传入目标类的Class类型来把JSON字符串反序列化为对应对象,单个对象场景下正常工作:

fun <T> deserializeJsonStr(jsonString: String, dataClassType: Class<T>): T? {
    var ret: T? = Gson().fromJson<T>(jsonString, dataClassType)
    return ret
}

比如针对TestData1类和单个对象的JSON:

// 数据模型
class TestData1 {
    var userId = 0
    var id = 0
    var title: String? = null
    var body: String? = null
}

// JSON字符串
{
      "userId": 1,
      "id": 3,
      "title": "the title",
      "body": "the body"
}

// 调用函数
val clazz: Class<TestData1> = TestData1::class.java
val theTestData1 = deserializeJsonStr(jsonString, clazz)

能正常得到填充好的TestData1对象。但遇到JSON数组时,想要反序列化为ArrayList<TestData1>,尝试传递Class类型时编译失败:

// 编译报错
val clazz: Class<ArrayList<TestData1>> = ArrayList<TestData1>::class.java
val theTestData1 = deserializeJsonStr(jsonString, clazz)

用ArrayList<>::class.java也无法通过编译,请问该怎么处理JSON数组的反序列化,或者说如何获取符合要求的ArrayList<TestData1>对应的Class类型?


解决方案

1. 编译失败的原因

Java/Kotlin存在泛型类型擦除机制,运行时ArrayList<TestData1>和ArrayList<String>的Class对象完全相同(都是ArrayList::class.java),无法直接获取带泛型参数的Class<ArrayList<TestData1>>,因此强转操作会触发编译错误。

2. 两种可行解决方式

方式一:修改函数,使用Gson的TypeToken保留泛型信息

Gson提供了TypeToken来规避泛型类型擦除问题,调整原函数支持该类型即可:

fun <T> deserializeJsonStr(jsonString: String, typeToken: TypeToken<T>): T? {
    return Gson().fromJson(jsonString, typeToken.type)
}

调用时通过匿名内部类创建TypeToken指定泛型类型:

val typeToken = object : TypeToken<ArrayList<TestData1>>() {}
val dataList = deserializeJsonStr(jsonString, typeToken)

方式二:先反序列化为数组,再转成ArrayList

如果不想修改原函数,可以利用数组类型信息不被完全擦除的特性,先反序列化为TestData1数组,再转换为ArrayList:

// 反序列化为TestData1数组
val arrayClazz: Class<Array<TestData1>> = Array<TestData1>::class.java
val dataArray = deserializeJsonStr(jsonString, arrayClazz)
// 转换为ArrayList
val dataList = dataArray?.toCollection(ArrayList())

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.15 22:20:34