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

仅通过修改Person类添加Jackson注解实现混合类型无泛型List的正确反序列化

仅通过修改Person类添加Jackson注解实现混合类型无泛型List的正确反序列化

嘿,这个问题我太熟悉了!你碰到的核心问题是:当反序列化无泛型声明的List时,Jackson没法知道列表里的对象具体是什么类型,所以默认把JSON对象转成了LinkedHashMap,这就导致后面强转Person时抛出ClassCastException。

好消息是,完全可以只通过给Person类添加Jackson注解来解决,不用修改你的测试代码,也不用开启全局默认类型。下面是具体方案:

解决方案:给Person类添加@JsonTypeInfo注解

我们可以让Jackson在序列化Person对象时,自动把类的类型信息写入JSON中;反序列化时,Jackson就能通过这个类型信息识别出该节点要转成Person对象,而不是LinkedHashMap。

修改后的Person类代码如下:

import com.fasterxml.jackson.annotation.JsonTypeInfo;

public static class Person {
    private String name;
    private String surname;

    // 核心注解:序列化时写入类的全限定名作为类型标识
    @JsonTypeInfo(
        use = JsonTypeInfo.Id.CLASS,
        include = JsonTypeInfo.As.PROPERTY,
        property = "@class" // 自定义类型属性名,你也可以改成"type"之类的
    )
    public Person() {
        // 必须保留无参构造器,Jackson反序列化时需要用到
    }

    public Person(String name, String surname) {
        this.name = name;
        this.surname = surname;
    }

    // 别忘了添加Getters和Setters
    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getSurname() {
        return surname;
    }

    public void setSurname(String surname) {
        this.surname = surname;
    }
}

为什么这个方案可行?

  1. 序列化阶段:当你把List转成JSON时,Person对象会被额外加上一个@class属性,值是Person类的全限定名(比如de.mpg.ipp.codac.archivedb.restapi.JsonTestsPlayground$Person),而Integer 23这类基本类型不受影响。
  2. 反序列化阶段:Jackson读到带有@class属性的JSON节点时,会自动根据这个属性值找到对应的Person类,把JSON转成Person实例,而不是默认的LinkedHashMap。

注意事项

  • 必须保留Person类的无参构造器:Jackson在反序列化对象时,默认会调用无参构造器来创建实例。
  • 如果你不想用类的全限定名作为类型标识,也可以把use改成JsonTypeInfo.Id.NAME,然后配合@JsonSubTypes注解给Person指定一个别名,不过用Id.CLASS更直接,不需要额外配置别名,适合你这种没有父类的场景。

这样修改之后,你的测试代码就能正常运行,outList.get(1)反序列化出来的就是Person对象,强转时不会再抛出异常啦!

备注:内容来源于stack exchange,提问作者primož perušek

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.21 08:42:59