首页 > Java > java教程 > 正文

如何使用 Gson 序列化多态对象并在 JSON 输出中保留继承的成员?

Linda Hamilton
发布: 2024-10-31 21:09:02
原创
560 人浏览过

How do you serialize polymorphic objects with Gson and preserve inherited members in the JSON output?

使用 Gson 序列化多态对象

Gson 是一个流行的 Java 库,用于将 Java 对象与 JSON 相互转换。使用 Gson 序列化对象的一个​​挑战是处理多态性,其中多个子类继承自一个公共超类。

问题

考虑一个场景,其中您有一个类层次结构,其中基类 ObixBaseObj 和多个继承类(如 ObixOp)。目标是使用 Gson 将这些类的对象序列化为 JSON,同时保留继承的成员(例如 ObixOp 的 in 和 out)。

GsonSerialization 示例

<code class="java">ObixBaseObj lobbyObj = new ObixBaseObj();
lobbyObj.setIs("obix:Lobby");

ObixOp batchOp = new ObixOp();
batchOp.setName("batch");
batchOp.setIn("obix:BatchIn");
batchOp.setOut("obix:BatchOut");

lobbyObj.addChild(batchOp);

Gson gson = new Gson();
System.out.println(gson.toJson(lobbyObj));</code>
登录后复制

结果

<code class="json">{"obix":"obj","is":"obix:Lobby","children":[{"obix":"op","name":"batch"}]}</code>
登录后复制

请注意,序列化的 JSON 不包含 ObixOp 的继承成员(in 和 out)。

RuntimeTypeAdapterFactory 解决方案

为了优雅地处理多态性,Gson 提供了一个强大的功能,称为 RuntimeTypeAdapterFactory。该类自动将子类注册到相应的超类中进行序列化和反序列化。

实现

<code class="java">RuntimeTypeAdapterFactory<ObixBaseObj> adapter = 
                    RuntimeTypeAdapterFactory
                   .of(ObixBaseObj.class)
                   .registerSubtype(ObixBaseObj.class)
                   .registerSubtype(ObixOp.class);


Gson gson2=new GsonBuilder().setPrettyPrinting().registerTypeAdapterFactory(adapter).create();
Gson gson = new Gson();
System.out.println(gson.toJson(lobbyObj));
System.out.println("---------------------");
System.out.println(gson2.toJson(lobbyObj));</code>
登录后复制

结果

<code class="json">{"obix":"obj","is":"obix:Lobby","children":[{"obix":"op","name":"batch","children":[]}]}
---------------------
{
  "type": "ObixBaseObj",
  "obix": "obj",
  "is": "obix:Lobby",
  "children": [
    {
      "type": "ObixOp",
      "in": "obix:BatchIn",
      "out": "obix:BatchOut",
      "obix": "op",
      "name": "batch",
      "children": []
    }
  ]
}</code>
登录后复制

这个解决方案正确序列化了所有成员,包括子类继承的成员。

处理多个子类

在有多个子类的情况下,Gson 的 RuntimeTypeAdapter 提供了一种方便的机制来注册它们。

  1. 创建一个用于注册类型的集中类(例如 GsonUtils):
<code class="java">public class GsonUtils {

    private static final GsonBuilder gsonBuilder = new GsonBuilder()
            .setPrettyPrinting();

    public static void registerType(
            RuntimeTypeAdapterFactory<?> adapter) {
        gsonBuilder.registerTypeAdapterFactory(adapter);
    }

    public static Gson getGson() {
        return gsonBuilder.create();
    }
}</code>
登录后复制
  1. 在子类中注册适配器:
<code class="java">public class ObixBaseObj {

    private static final RuntimeTypeAdapterFactory<ObixBaseObj> adapter = 
            RuntimeTypeAdapterFactory.of(ObixBaseObj.class);

    static {
        GsonUtils.registerType(adapter);
    }

    private synchronized void registerClass() {
        if (!registeredClasses.contains(this.getClass())) {
            registeredClasses.add(this.getClass());
            adapter.registerSubtype(this.getClass());
        }
    }

    public ObixBaseObj() {
        registerClass();
        obix = "obj";
    }
}</code>
登录后复制

这种方法可确保所有子类自动注册到 GsonBuilder,从而简化序列化过程。

以上是如何使用 Gson 序列化多态对象并在 JSON 输出中保留继承的成员?的详细内容。更多信息请关注PHP中文网其他相关文章!

来源:php.cn
本站声明
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn
作者最新文章
热门教程
更多>
最新下载
更多>
网站特效
网站源码
网站素材
前端模板