Gson Advanced — 泛型

作者: 無名小子的杂货铺 | 来源:发表于2016-12-05 16:35 被阅读1131次

    原文链接:Gson Advanced — Generics
    原文出自:Norman Peitek
    译者:無名無

    本文将介绍使用 Gson 来解析 Java 泛型类型的数据结构,如果不了解泛型基本知识的可以回顾 Wikipedia article,同样 Gson 会帮我们完成解析。

    泛型序列化

    之前使用 Gson 来解析 Java 对象,我们必须传入要解析的 Java class 类型,先来看例子。

    两个 List:

    Gson gson = new Gson();
    
    List<Integer> integerList = new ArrayList<>();  
    integerList.add(1);  
    integerList.add(2);  
    integerList.add(3);
    
    List<String> 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<Integer> integerList = new ArrayList<>();  
    integerList.add(1);  
    integerList.add(2);  
    integerList.add(3);
    
    List<String> stringList = new ArrayList<>();  
    stringList.add("1");  
    stringList.add("2");  
    stringList.add("3");
    
    Type integerType = new TypeToken<List<Integer>>() {}.getType();  
    Type stringType = new TypeToken<List<String>>() {}.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<T> {  
        private T boxContent;
    
        public Box(T t) {
            this.boxContent = t;
        }
    }
    
    Gson gson = new Gson();
    
    Box<String> stringBox = new Box<>("String Type");  
    Box<Integer> 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<UserDate> complexBox = new Box<>(new UserDate("Norman", "norman@fs.io", 26, true));
    
    Type stringType = new TypeToken<Box<String>>() {}.getType();  
    Type integerType = new TypeToken<Box<Integer>>() {}.getType();  
    Type complexType = new TypeToken<Box<UserDate>>() {}.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":"norman@fs.io","isDeveloper":true,"age":26,"registerDate":"Dec 4, 2016 10:21:24 AM"}}
    

    反序列化泛型

    假设有一段这样的 JSON 数据,我们使用 Box 泛型来解析。

    {
      "boxContent": {
        "_name": "Norman",
        "age": 26,
        "email": "norman@fs.io",
        "isDeveloper": true,
        "registerDate": "Jun 7, 2016 7:15:29 AM"
      }
    }
    

    首先我们要明确 JSON 属于 Box 中泛型的哪种类型,知道了泛型的类型,我们就能确认 TypeToken 的类型。

    String complexGenericJson = "{\"boxContent\":{\"_name\":\"Norman\",\"age\":26,\"email\":\"norman@fs.io\",\"isDeveloper\":true,\"registerDate\":\"Jun 7, 2016 7:15:29 AM\"}}";
    
    Type complexType = new TypeToken<Box<UserDate>>() {}.getType();
    
    Gson gson = new Gson();  
    Box boxWithData = gson.fromJson(complexGenericJson, complexType);  
    Box<UserDate> 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=norman@fs.io, isDeveloper=true, registerDate=Jun 7, 2016 7:15:29 AM}}
    boxWithData:Box{boxContent=UserDate{_name='Norman', email='norman@fs.io', 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 开源库分享学习群,有兴趣的小伙伴可以加入一起学习。

    群二维码

    相关文章

      网友评论

        本文标题:Gson Advanced — 泛型

        本文链接:https://www.haomeiwen.com/subject/jhkhmttx.html