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

Gson序列化/反序列化抽象类问题:LinkedList<Request>反序列化失败

解决Gson反序列化LinkedList含抽象类子类的崩溃问题

我之前也遇到过几乎一模一样的问题——用Gson反序列化包含抽象类Parameter子类的LinkedList<Request>时总是崩溃,结合你的代码来看,问题核心有两个:

  1. Gson默认无法识别抽象类对应的具体子类,JSON里没有类型标识的话,它不知道该实例化StringParameter还是PasswordParameter
  2. Lombok的@SuperBuilder和@Builder生成的构造逻辑,和Gson默认依赖的无参构造/字段赋值逻辑不兼容

下面是我亲测有效的解决步骤:

1. 给抽象类添加类型标识字段

首先要让JSON里带上能区分子类的标识,这样反序列化时能判断具体类型。修改你的Parameter抽象类,新增一个type字段:

@Data
@SuperBuilder
@NoArgsConstructor(access = AccessLevel.PROTECTED) // 给Gson提供实例化入口
public abstract class Parameter implements Serializable {
    private String key;
    private String type; // 类型标识,比如"string"或"password"
    public abstract Object getValue();
}

然后在子类里自动初始化type的值,确保序列化时这个字段会被写入JSON:

@Data
@SuperBuilder
@EqualsAndHashCode(callSuper = true)
@NoArgsConstructor // 新增无参构造,兼容Gson
public class StringParameter extends Parameter implements Serializable {
    private String value;

    @Override
    public Object getValue() {
        return value;
    }

    // 初始化类型标识
    private void initType() {
        setType("string");
    }

    // 利用Lombok的构造后钩子设置类型
    @PostConstruct
    private void postConstruct() {
        initType();
    }

    // 确保Builder创建实例时自动设置type
    public static class StringParameterBuilder extends Parameter.ParameterBuilder<StringParameter, StringParameterBuilder> {
        public StringParameterBuilder() {
            type("string");
        }
    }
}

PasswordParameter做类似修改,把type设为"password"即可。

2. 编写自定义Parameter反序列化器

接下来要写一个Gson的反序列化器,根据type字段的值,选择对应的子类实例化,同时兼容Lombok的Builder:

public class ParameterDeserializer implements JsonDeserializer<Parameter> {
    @Override
    public Parameter deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) throws JsonParseException {
        JsonObject jsonObj = json.getAsJsonObject();
        String paramType = jsonObj.get("type").getAsString();
        String key = jsonObj.get("key").getAsString();
        String value = jsonObj.get("value").getAsString();

        switch (paramType) {
            case "string":
                return StringParameter.builder()
                        .key(key)
                        .value(value)
                        .type(paramType)
                        .build();
            case "password":
                return PasswordParameter.builder()
                        .key(key)
                        .value(value)
                        .type(paramType)
                        .build();
            default:
                throw new JsonParseException("Unsupported parameter type: " + paramType);
        }
    }
}

3. 注册反序列化器并构建Gson实例

最后把自定义的反序列化器注册到Gson里,然后就可以正常反序列化LinkedList<Request>了:

// 构建带自定义反序列化器的Gson实例
Gson gson = new GsonBuilder()
        .registerTypeAdapter(Parameter.class, new ParameterDeserializer())
        .create();

// 反序列化LinkedList<Request>,注意用TypeToken指定泛型类型
String jsonStr = "你的JSON字符串";
LinkedList<Request> requestList = gson.fromJson(jsonStr, new TypeToken<LinkedList<Request>>() {}.getType());

额外注意事项

  • 如果你的Request类用了@Builder,要确保它也添加@NoArgsConstructor,否则Gson可能无法实例化Request对象
  • 测试序列化后的JSON,确认每个Parameter都带有type字段,这是反序列化的关键
  • 如果还是有问题,可以尝试关闭Gson的serializeNulls配置,避免空值字段干扰反序列化逻辑

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.09 14:22:29