Gson Advanced — 映射循環引用

原文鏈接:Gson Advanced — Mapping of Circular References
原文出自:Norman Peitek
譯者:無名無

本文來看一個非常特殊的情況:循環引用。類似死鎖的現象,產生了相互引用,也就是我中有你,你中有我,如果你用 Gson 來序列化,那麼 Gson 判斷引用情況也就沒完沒了了,最終會產生崩潰,接下來我們將分析病解決這種情況。

StackOverflowError

我們只看序列化情況,根據之前瞭解的嵌套對象,我們知道,如果對象 A 引用 對象 B ,那麼 Gson 會在 A 中創建一個新的字元素,用”{}”來包裝,這是正常的情況,但是,在這基礎上,如果 B 對象又引用了 A,這就會產生無限死循環,無限的創建子元素,最終產生 StackOverflowError 錯誤。

定義一個類:

 public class UserCircular {  
    String name;
    String email;
    int age;
    boolean isDeveloper;

    // references to child & parent node
    UserCircular child;
    UserCircular parent;
}

看這個類就明白,UserCircular 嵌套了 child 和 parent,child 和 parent 都是 UserCircular 類型,也就是說產生了死循環,我們無法序列化它。

解決:我們必須從序列化類排除另一個引用,使用 transient 修飾 UserCircular parent。

例如:

public class UserCircular {  
    String name;
    String email;
    int age;
    boolean isDeveloper;

    // references to child & parent node
    UserCircular child;
    transient UserCircular parent;
}

這樣 parent 將無法序列化,也就無法產生死循環。

輸出:

{
  "age": 26,
  "child": {
    "age": 26,
    "email": "[email protected]",
    "isDeveloper": true,
    "name": "Norman"
  },
  "email": "[email protected]",
  "isDeveloper": true,
  "name": "Norman"
}

目標

瞭解 StackOverflowError 產生的原因,並修復這個問題。

練習代碼已上傳 Github https://github.com/whiskeyfei/Gson-Review 可自行查看。

Gson 系列文章翻譯回顧

1、Gson - Java-JSON 序列化和反序列化入門
2、Gson - 映射嵌套對象
3、Gson - Arrays 和 Lists 映射對象
4、Gson - Map 結構映射
5、Gson - Set 集合映射
6、Gson - 空值映射
7、Gson Model Annotations - 如何使用 @SerializedName 更改字段的命名
8、Gson Model Annotations - @SerializedName 匹配多個反序列化名稱
9、Gson Builder - 基礎和命名規則
10、Gson Builder - 序列化空值
11、Gson Builder - 忽略策略
12、Gson Builder - Gson Lenient 屬性
13、Gson Builder - 特殊類型 Floats & Doubles
17、Gson Builder - 如何使用 @Expose 忽略字段
19、Gson Advanced - 映射枚舉類型
20、Gson Advanced - 映射循環引用
21、Gson Advanced - 泛型
22、Gson Advanced - 簡單自定義序列化 (Part 1)
24、Gson Advanced - 自定義反序列化基礎
25、Gson Advanced - 自定義對象實例創建
26、Gson Advanced - 通過 @JsonAdapter 自定義(反)序列化過程
32、Practical Gson - 如何解析多態對象

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章