ホームページ  >  記事  >  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 オブジェクトと JSON 間の変換に使用される人気のある Java ライブラリです。 Gson でオブジェクトをシリアル化する際の 1 つの課題は、複数のサブクラスが共通のスーパークラスから継承するポリモーフィズムを処理することです。

問題

クラス階層があるシナリオを考えてみましょう。基本クラス ObixBaseObj と、ObixOp などの複数の継承クラス。目標は、継承されたメンバー (ObixOp の in および out など) を保持しながら、Gson を使用してこれらのクラスのオブジェクトを JSON にシリアル化することです。

GsonSerialization Example

<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 の継承メンバー (インおよびアウト) が含まれていないことに注意してください。

RuntimeTypeAdapterFactory Solution

ポリモーフィズムを適切に処理するために、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 中国語 Web サイトの他の関連記事を参照してください。

声明:
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。