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

Gson反序列化仅生成父类实例问题求助

解决Gson反序列化父类字段仅生成父类实例的问题

这个问题我之前也碰到过!Gson默认是按照字段的声明类型来反序列化的——哪怕你初始化时给的是Fool2子类实例,序列化后再反序列化,Gson只会认Fool这个声明类型,自然就只创建Fool实例了。不过有两种靠谱的解决办法:

方法一:使用官方的RuntimeTypeAdapterFactory(推荐)

Gson的扩展库gson-extras提供了RuntimeTypeAdapterFactory,专门用来处理多态类型的序列化/反序列化,这是最简洁可靠的方案。

步骤1:引入依赖

如果用Maven,在pom.xml里添加:

<dependency>
    <groupId>com.google.code.gson</groupId>
    <artifactId>gson-extras</artifactId>
    <version>2.10.1</version> <!-- 建议使用最新稳定版 -->
</dependency>

步骤2:编写代码实现

注意:你的自定义类名不要用Object,会和java.lang.Object冲突,我改成MyObject了:

// 父类
public class Fool {}

// 子类
public class Fool2 extends Fool {}

// 包含Fool字段的类
public class MyObject {
    private Fool fool = new Fool2();
}

// 测试类
public class GsonPolymorphicDemo {
    public static void main(String[] args) {
        // 创建类型适配器工厂,指定父类Fool,用"type"字段区分子类
        RuntimeTypeAdapterFactory<Fool> typeFactory = RuntimeTypeAdapterFactory.of(Fool.class, "type")
                .registerSubtype(Fool2.class, "fool2"); // 注册子类并指定标识值

        // 构建带有该工厂的Gson实例
        Gson gson = new GsonBuilder()
                .registerTypeAdapterFactory(typeFactory)
                .create();

        // 序列化
        MyObject original = new MyObject();
        String json = gson.toJson(original);
        System.out.println(json); // 输出会包含"type":"fool2"字段

        // 反序列化
        MyObject deserialized = gson.fromJson(json, MyObject.class);
        System.out.println(deserialized.fool.getClass()); // 输出class Fool2,符合预期
    }
}

这个工厂会在序列化时自动添加一个标识字段(比如这里的"type"),反序列化时根据这个字段判断应该实例化哪个子类。

方法二:手动存储类路径

如果你不想引入额外依赖,可以手动在序列化时存储子类的全限定类名,反序列化时根据类名创建实例:

import com.google.gson.Gson;
import com.google.gson.JsonObject;

public class ManualTypeHandlingDemo {
    // 自定义类(避免和系统Object冲突)
    public static class MyObject {
        private Fool fool = new Fool2();
        // 用于存储子类的类路径
        private String foolClassType;

        // 序列化前先设置类路径
        public void prepareForSerialize() {
            this.foolClassType = fool.getClass().getName();
        }
    }

    public static void main(String[] args) throws Exception {
        Gson gson = new Gson();
        MyObject original = new MyObject();
        original.prepareForSerialize();

        // 序列化
        String json = gson.toJson(original);

        // 反序列化第一步:解析JSON对象,获取类路径
        JsonObject jsonObj = gson.fromJson(json, JsonObject.class);
        String classPath = jsonObj.get("foolClassType").getAsString();
        Class<? extends Fool> subclass = (Class<? extends Fool>) Class.forName(classPath);

        // 反序列化fool字段到具体子类
        Fool fool = gson.fromJson(jsonObj.get("fool"), subclass);
        MyObject deserialized = new MyObject();
        deserialized.fool = fool;

        System.out.println(deserialized.fool.getClass()); // 输出class Fool2
    }
}

这种方法需要手动处理类路径的存储和解析,适合不想引入额外依赖的场景,但代码相对繁琐一些。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.13 08:52:17