原文链接:Gson Advanced — Generics
原文出自:Norman Peitek
译者:無名無
本文将介绍使用 Gson 来解析 Java 泛型类型的数据结构,如果不了解泛型基本知识的可以回顾 Wikipedia article,同样 Gson 会帮我们完成解析。
泛型序列化
之前使用 Gson 来解析 Java 对象,我们必须传入要解析的 Java class 类型,先来看例子。
两个 List:
Gson gson = new Gson();
List integerList = new ArrayList<>();
integerList.add(1);
integerList.add(2);
integerList.add(3);
List stringList = new ArrayList<>();
stringList.add("1");
stringList.add("2");
stringList.add("3");
String integerJson = gson.toJson(integerList);
String stringJson = gson.toJson(stringList);
每种数据类型需要 new TypeToken 才能解析成功:
Gson gson = new Gson();
List integerList = new ArrayList<>();
integerList.add(1);
integerList.add(2);
integerList.add(3);
List stringList = new ArrayList<>();
stringList.add("1");
stringList.add("2");
stringList.add("3");
Type integerType = new TypeToken>() {}.getType();
Type stringType = new TypeToken>() {}.getType();
String integerJson = gson.toJson(integerList, integerType);
String stringJson = gson.toJson(stringList, stringType);
输出:
integerJson = "[1,2,3]"
stringJson = "["1","2","3"]"
再来看一个泛型封装的例子 Box,只包含了一个泛型对象:
public class Box {
private T boxContent;
public Box(T t) {
this.boxContent = t;
}
}
Gson gson = new Gson();
Box stringBox = new Box<>("String Type");
Box integerBox = new Box<>(42);
// the class UserDate is from previous guides (https://futurestud.io/blog/gson-builder-formatting-of-dates-custom-date-time-mapping/)
Box complexBox = new Box<>(new UserDate("Norman", "[email protected]", 26, true));
Type stringType = new TypeToken>() {}.getType();
Type integerType = new TypeToken>() {}.getType();
Type complexType = new TypeToken>() {}.getType();
String integerJson = gson.toJson(integerBox, integerType);
String stringJson = gson.toJson(stringBox, stringType);
String complexJson = gson.toJson(complexBox, complexType);
输出:
integerJson:{"boxContent":42}
stringJson:{"boxContent":"String Type"}
complexJson:{"boxContent":{"_name":"Norman","email":"[email protected]","isDeveloper":true,"age":26,"registerDate":"Dec 4, 2016 10:21:24 AM"}}
反序列化泛型
假设有一段这样的 JSON 数据,我们使用 Box 泛型来解析。
{
"boxContent": {
"_name": "Norman",
"age": 26,
"email": "[email protected]",
"isDeveloper": true,
"registerDate": "Jun 7, 2016 7:15:29 AM"
}
}
首先我们要明确 JSON 属于 Box 中泛型的哪种类型,知道了泛型的类型,我们就能确认 TypeToken 的类型。
String complexGenericJson = "{\"boxContent\":{\"_name\":\"Norman\",\"age\":26,\"email\":\"[email protected]\",\"isDeveloper\":true,\"registerDate\":\"Jun 7, 2016 7:15:29 AM\"}}";
Type complexType = new TypeToken>() {}.getType();
Gson gson = new Gson();
Box boxWithData = gson.fromJson(complexGenericJson, complexType);
Box boxWithoutData = gson.fromJson(complexGenericJson, Box.class);
System.out.println("boxWithoutData:" + boxWithoutData);
System.out.println("boxWithData:" + boxWithData);
输出:
boxWithoutData:Box{boxContent={_name=Norman, age=26.0, [email protected], isDeveloper=true, registerDate=Jun 7, 2016 7:15:29 AM}}
boxWithData:Box{boxContent=UserDate{_name='Norman', email='[email protected]', isDeveloper=true, age=26, registerDate=Tue Jun 07 07:15:29 CST 2016}}
解析泛型的关键就是我们要知道最终要解析成那种泛型类型。如果你想知道更多关于 Gson 如何处理内部 Java 泛型的,可以阅读 [official user guide](official user guide)
目标
了解 Gson 泛型使用,针对泛型解析有一些需要注意的情况以及实际应用。
练习代码已上传 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 - 如何解析多态对象
学习讨论
刚刚建了一个 Android 开源库分享学习群,有兴趣的小伙伴可以加入一起学习。