原文鏈接: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 - 如何解析多態對象