使用 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 提供了一種方便的機制來註冊它們。
<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>
<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>
以上是如何使用 Gson 序列化多態物件並在 JSON 輸出中保留繼承的成員?的詳細內容。更多資訊請關注PHP中文網其他相關文章!