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

无界泛型同质集合的Jackson自定义反序列化器最优实现方案

问题原因

Java泛型存在运行时类型擦除,你声明的List<Set<?>>在运行时对Jackson而言仅为原生List类型,无法识别内层集合存储的具体元素类型,因此遇到自定义对象结构时Jackson会默认反序列化为LinkedHashMap。

解决方案

方案1:启用Jackson原生多态类型处理(最推荐)

Jackson原生支持序列化时附加类型信息、反序列化时自动转换对应类型,无需自行实现序列化/反序列化逻辑,仅需少量配置:

// 方式一:仅给需要类型识别的自定义类加注解,安全性更高
import com.fasterxml.jackson.annotation.JsonTypeInfo;

@JsonTypeInfo(use = JsonTypeInfo.Id.CLASS, include = JsonTypeInfo.As.PROPERTY, property = "@class")
record Item(String id) {}

如果需要全局生效所有非基础类型,可以配置ObjectMapper:

ObjectMapper mapper = new ObjectMapper();
// 注意:全局类型配置仅建议在内部可信场景使用,对外接口使用需防范反序列化注入风险
mapper.activateDefaultTyping(
    LaissezFaireSubTypeValidator.instance,
    ObjectMapper.DefaultTyping.NON_FINAL,
    JsonTypeInfo.As.PROPERTY
);

配置完成后原测试代码无需修改其他逻辑,即可直接通过断言。

方案2:反序列化后手动转换

如果你不想修改原有JSON结构、也不想添加额外类型字段,可以用Jackson自带的convertValue方法二次转换结果,无需自行解析JSON:

Root parsed = mapper.readValue(json, Root.class);
// 手动转换对应位置的集合元素类型
Set<Item> actualSecondSet = mapper.convertValue(
    parsed.data().get(1),
    new TypeReference<Set<Item>>() {}
);
assertEquals(secondSet, actualSecondSet);

该方案适合临时兼容场景,无需调整原有序列化逻辑。

方案3:简化自定义反序列化器(复用Jackson原生能力)

如果你确实需要保留自定义TypedList容器结构,可以直接调用Jackson内置的集合反序列化能力,无需自行遍历JSON令牌:

class TypedCollectionDeserializer<T> extends StdDeserializer<TypedList<T>> {
    public TypedCollectionDeserializer() {
        super(TypedList.class);
    }

    @Override
    public TypedList<T> deserialize(JsonParser p, DeserializationContext ctxt) throws IOException {
        // 读取类型字段
        p.nextFieldName();
        Class<T> elementType = (Class<T>) Class.forName(p.nextTextValue());
        // 读取数据字段,直接用Jackson内置逻辑反序列化为指定类型的集合
        p.nextFieldName();
        List<T> data = ctxt.readValue(
            p,
            ctxt.getTypeFactory().constructCollectionType(List.class, elementType)
        );
        return new TypedList<>(elementType, data);
    }
}

该方案避免了重复实现集合解析逻辑,同时保留了你自定义容器的需求。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.27 00:24:04