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

Gson泛型类型适配器基类反序列化:基类与子类适配异常

解决Gson继承类反序列化:基类Kit解析失败的问题

这个问题我之前也碰到过,核心是Gson默认对继承关系的反序列化支持不够灵活,加上你注册的类型适配器可能只适配了子类ExtendedKit,导致解析基类Kit的JSON时,因为找不到子类特有的extraProperty字段而报错。下面给你两个实用的解决方案,不用写大量类型适配器就能搞定:

方案1:使用RuntimeTypeAdapterFactory(官方推荐)

Gson有个专门处理多态反序列化的扩展类RuntimeTypeAdapterFactory,它通过在JSON里添加一个类型标识字段,来区分要解析成基类还是子类,扩展性很强,适合有多个子类的场景。

步骤:

  1. 先创建类型适配器工厂,指定基类、类型标识字段名,然后注册所有子类:
// 需引入com.google.gson:gson-extras依赖(如果项目还没添加)
RuntimeTypeAdapterFactory<Kit> kitTypeFactory = RuntimeTypeAdapterFactory.of(Kit.class, "type")
    .registerSubtype(Kit.class, "kit") // 基类对应的类型标识值
    .registerSubtype(ExtendedKit.class, "extendedKit"); // 子类对应的类型标识值
  1. 将这个工厂注册到GsonBuilder:
Gson gson = new GsonBuilder()
    .registerTypeAdapterFactory(kitTypeFactory)
    .create();
  1. 对应的JSON格式需要带上类型标识:
  • 基类Kit的JSON:
{"type":"kit", "baseProperty":"value"}
  • 子类ExtendedKit的JSON:
{"type":"extendedKit", "baseProperty":"value", "extraProperty":"extraValue"}

这样Gson会根据type字段自动选择对应的类进行反序列化,基类和子类都能正常解析。

方案2:自定义通用类型适配器(无需类型标识字段)

如果不想在JSON里加额外的类型标识字段,可以写一个针对基类Kit的自定义适配器,通过判断JSON中是否存在子类特有的字段,来决定实例化哪个类。

实现代码:

public class KitTypeAdapter extends TypeAdapter<Kit> {
    // 用默认Gson处理具体的序列化/反序列化逻辑
    private final Gson defaultGson = new Gson();

    @Override
    public void write(JsonWriter out, Kit value) throws IOException {
        // 序列化时判断对象实际类型,对应写入JSON
        if (value instanceof ExtendedKit) {
            defaultGson.toJson(value, ExtendedKit.class, out);
        } else {
            defaultGson.toJson(value, Kit.class, out);
        }
    }

    @Override
    public Kit read(JsonReader in) throws IOException {
        // 先把JSON读成JsonElement,方便后续判断字段
        JsonElement jsonElement = defaultGson.fromJson(in, JsonElement.class);
        JsonObject jsonObject = jsonElement.getAsJsonObject();

        // 判断是否存在子类ExtendedKit特有的字段extraProperty
        if (jsonObject.has("extraProperty")) {
            return defaultGson.fromJson(jsonElement, ExtendedKit.class);
        } else {
            return defaultGson.fromJson(jsonElement, Kit.class);
        }
    }
}

注册适配器:

Gson gson = new GsonBuilder()
    .registerTypeAdapter(Kit.class, new KitTypeAdapter())
    .create();

这样处理后,不管是带extraProperty的子类JSON,还是不带的基类JSON,都能被正确解析,不会因为找不到字段而报错。

注意事项

  • 如果之前你只注册了ExtendedKit的类型适配器,Gson在解析Kit类型时可能会因为类型擦除,错误地尝试用子类的适配器解析,导致报错。所以一定要针对基类来注册适配器,覆盖所有子类的情况。
  • 方案1的RuntimeTypeAdapterFactory属于Gson的扩展库,需要确保你的项目中引入了gson-extras依赖(Maven/Gradle均可配置)。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.19 10:43:59