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

Gson反序列化字节数组为泛型T返回LinkedTreeMap的解决问询

解决Gson泛型反序列化返回LinkedTreeMap的问题

问题根源

Java的泛型擦除机制导致运行时无法获取T的实际类型信息。你代码里的new TypeToken<T>(){}.getType(),由于泛型擦除,拿到的只是Object类型(或泛型占位符),而非你期望的具体泛型类型(比如嵌套的A<B>)。Gson无法识别目标类型,只能默认解析成LinkedTreeMap。

解决方案:保留实际泛型类型信息

要让Gson知道具体的目标类型,必须在创建JsonDeserializer实例时,显式传入包含完整泛型信息的TypeToken,而非依赖擦除后的泛型参数T。

修改后的JsonDeserializer实现

import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import com.google.gson.reflect.TypeToken;
import java.lang.reflect.Type;
import java.nio.charset.StandardCharsets;

public class JsonDeserializer<T> implements Deserializer<T> {
    private final Type targetType;

    // 构造器传入包含完整泛型信息的TypeToken
    public JsonDeserializer(TypeToken<T> typeToken) {
        this.targetType = typeToken.getType();
    }

    // 静态工厂方法,简化实例创建
    public static <T> JsonDeserializer<T> forType(TypeToken<T> typeToken) {
        return new JsonDeserializer<>(typeToken);
    }

    @Override
    public T deserialize(String topic, byte[] data) {
        if (data == null) {
            return null;
        }
        Gson gson = new GsonBuilder().create();
        return gson.fromJson(new String(data, StandardCharsets.UTF_8), targetType);
    }
}

使用方式

无论是普通实体类还是嵌套泛型类,都可以通过TypeToken指定完整类型:

// 普通实体类示例(如Patient)
JsonDeserializer<Patient> patientDeserializer = JsonDeserializer.forType(new TypeToken<Patient>() {});

// 嵌套泛型示例(如Response<Patient>)
JsonDeserializer<Response<Patient>> responseDeserializer = JsonDeserializer.forType(new TypeToken<Response<Patient>>() {});

原理说明

TypeToken通过创建匿名内部类的方式,在编译阶段将泛型的实际类型信息写入字节码的Signature属性中。运行时通过getType()方法可以获取到包含嵌套泛型的完整ParameterizedType,Gson据此就能正确解析出目标对象,而非默认的LinkedTreeMap。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.13 21:55:39