首頁  >  文章  >  Java  >  如何使用 Gson 序列化多態物件並在 JSON 輸出中保留繼承的成員?

如何使用 Gson 序列化多態物件並在 JSON 輸出中保留繼承的成員?

Linda Hamilton
Linda Hamilton原創
2024-10-31 21:09:02477瀏覽

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 不包含的Obix繼承成員(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中文網其他相關文章!

陳述:
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn