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
相关产品推荐
相关产品推荐

