Gson

目前主流的json解析类库有jackson,fastjson,gson,gson的serialization deserialization解析功能无疑是最强大的,基本上完美支持复杂对象的json化和反json化,其他两个库在转换复杂对象时都容易出现问题。如果在不考虑效率的情况下,我强烈推荐使用gson类库。

首先需要添加依赖

//gradledependencies {compile 'com.google.code.gson:gson:2.8.2'
}//maven
<dependencies><!--  Gson: Java to Json conversion --><dependency><groupId>com.google.code.gson</groupId><artifactId>gson</artifactId><version>2.8.2</version><scope>compile</scope></dependency>
</dependencies>

接下来看一些代码例子,gson设计的非常易用,基本上一看就懂。

转换基础数据类型

// 创建gson对象,gson对象是内部无状态的,所以创建一个可以多次使用,可以想象成一个转换器
Gson gson = new Gson();
//转换成json只用直接放入对象就行,gson在内部会提取对象的类型信息
gson.toJson(1);            // ==> 1
gson.toJson("abcd");       // ==> "abcd"
gson.toJson(new Long(10)); // ==> 10
int[] values = { 1 };
gson.toJson(values);       // ==> [1]// 反json化,此时需要传入类型参数,因为json中是没有保存关于java类型的信息的
int one = gson.fromJson("1", int.class);
Integer one = gson.fromJson("1", Integer.class);
Long one = gson.fromJson("1", Long.class);
String str = gson.fromJson("\"abc\"", String.class);

转换对象类型

当然,gson也支持对对象类型的转换

class BagOfPrimitives {private int value1 = 1;private String value2 = "abc";//使用transient标识的变量不会被json化 private transient int value3 = 3;BagOfPrimitives() {// no-args constructor}
}// Serialization
BagOfPrimitives obj = new BagOfPrimitives();
Gson gson = new Gson();
String json = gson.toJson(obj);  // ==> json is {"value1":1,"value2":"abc"}

不过注意你不能json化一个具有循环引用的对象,会导致死循环(简单来说就是a有一个变量为b,b也有一个变量为a,此时无论json化谁都会导致死循环)

使用gson序列化对象的要点

1.完全可以使用private修饰变量类型,因为gson内部是使用反射来进行json化的,所以private也完全可以读取的到
2.完全没有必要使用任何的annotations 来标注哪个字段需要被包含(有很多其他库是使用annotations 来标记的),gson默认会序列化当前类中的所有字段(包括他的所有父类)
3.如果一个字段被标记为transient,他不会被Json化
4.gson对值为null的字段有很好的支持

转换数组类型

Gson gson = new Gson();
int[] ints = {1, 2, 3, 4, 5};
String[] strings = {"abc", "def", "ghi"};// Serialization
gson.toJson(ints);     // ==> [1,2,3,4,5]
gson.toJson(strings);  // ==> ["abc", "def", "ghi"]// Deserialization
int[] ints2 = gson.fromJson("[1,2,3,4,5]", int[].class); 

集合类型

java对集合类型是做了特殊支持的,输出的效果基本和数组一样,除了元素之外不会输出其他的字段例如 size之类的

        Gson gson = new Gson();Collection<Integer> ints = Arrays.asList(1,2,3,4,5);// SerializationString json = gson.toJson(ints);  // ==> json is [1,2,3,4,5]// Deserialization//对于泛型类型,因为直接取得的class并不包括泛型类型,所以需要创建type再传入Type collectionType = new TypeToken<Collection<Integer>>(){}.getType();Collection<Integer> ints2 = gson.fromJson(json, collectionType);

转换泛型类型

因为gson内部是使用getClass来获取类型信息,返回的类型都不包括泛型参数类型,所以直接像之前使用的话,序列化和反序列化都会失败
(其实不只是gson,java的泛型本身就被吐槽很久了,各种毛病)

class Foo<T> {T value;
}
Gson gson = new Gson();
Foo<Bar> foo = new Foo<Bar>();
gson.toJson(foo); //不能成功序列化gson.fromJson(json, foo.getClass()); // 无法反序列化

如果想要成功序列化带有泛型类型的对象,需要使用Type对象

//注意这里的TypeToken带有{},其实是一个匿名类,因为TypeToken的构造器是非Public的,不能直接构造,我也不太清楚为什么要这样设计
Type fooType = new TypeToken<Foo<Bar>>() {}.getType();
gson.toJson(foo, fooType);gson.fromJson(json, fooType);

转换带有混合类型的集合

有时候你可能会在一个集合中放入不同的类型(虽然我个人强烈不推荐这样写,因为泛型的作用就是为了省掉不必要的cast,你还放入不同类型,这不是自找麻烦吗?)
但是如果你真的这样写了,gson还是可以帮你转换

Collection collection = new ArrayList();
collection.add("hello");
collection.add(5);
collection.add(new Event("GREETINGS", "guest"));class Event {private String name;private String source;private Event(String name, String source) {this.name = name;this.source = source;}
}

你完全可以像直接一样直接序列化这个集合,没有任何问题。
但是之前也说过,json没有保存关于java对象类型的任何信息(作为一个通用的数据交换格式他这样做是正确的,否则这段json数据就只有gson才能解析了)。
之前我们在反序列化的同时都要手动传入类型参数,但是作为一个混合集合,显然没有一个所谓的’类型参数’,所以直接反序列化是不可能了。
如果你想要反序列化这样的json,有以下几种选择。
1.使用原始的json类库手动解析
2.注册一个collection 的adapter(我们下一篇会讲),自定义解析过程(还是需要手动解析)
所以如果想要反序列化这样的集合,无论怎么样都要手写解析,没什么办法,所以最好还是不要在泛型集合里放入不同的类型

要点总结

gson在序列化对象到json的过程中并没有保存对象的类型信息,所以在反序列化过程中,需要手动传入参数(就是你自己要清楚这个对象原来是什么)
因为我自己也写过简单的json转换类库,我说一下在json中如果保存java类型信息的好处和坏处
首先什么是在json中保存java的类型信息呢,就是例如使用一些额外的字段,将关于该对象本身类型的信息,也加入到json中。
好处:反序列化时不用输入类型参数,直接反序列化
坏处:json体积更大,而且直接序列化json的那个库,才能直接反序列化对应的json,其他的库就不行了,而且限定于java,因为类型信息只是关于java的

关于json的更多高级用法,我们会在下一篇中提及

Gson详解--入门篇相关推荐

  1. mhdd应用详解-入门篇(图文教程)

    mhdd应用详解-入门篇(图文教程) 来源:wxiu.com 作者:fox 时间:2009-03-13 点击: 54 对于专业的 电脑维修人员来说, MHDD是必备的硬盘工具,但是技术人员一般只拿他 ...

  2. WebSocket四种事件详解 入门篇(二)

    示例代码  在文章最下方,可以根据示例代码和讲解来理解整个WebSocket流程.代码用SpringBoot 和 maven搭建 服务端和客户端四种事件 1.打开事件 此事件发生在端点上建立新连接时并 ...

  3. IIS负载均衡-Application Request Route详解第一篇: ARR介绍

    IIS负载均衡-Application Request Route详解第一篇: ARR介绍   说到负载均衡,相信大家已经不再陌生了,本系列主要介绍在IIS中可以采用的负载均衡的软件:微软的Appli ...

  4. IIS负载均衡-Application Request Route详解第二篇:创建与配置Server Farm

    自从本系列发布之后,收到了很多的朋友的回复!非常感谢,同时很多朋友问到了一些问题,有些问题是一些比较基本的问题,由于时间的缘故,不会一一的为大家回复,如果有不明白的,希望大家勤自学!本系列虽然不难,但 ...

  5. IIS负载均衡-Application Request Route详解第二篇:创建与配置Server Farm(转载)

    IIS负载均衡-Application Request Route详解第二篇:创建与配置Server Farm 自从本系列发布之后,收到了很多的朋友的回复!非常感谢,同时很多朋友问到了一些问题,有些问 ...

  6. Linux使用详解(进阶篇)

    文章目录 Linux使用详解(进阶篇) 1.Linux目录说明 2.操作防火墙 3.ulimit命令和history命令 4.RPM和Yum的使用 5.设置系统字符集 6.vi & vim编辑 ...

  7. HSQLDB数据库使用详解(入门)及快速使用

    hsql数据库使用详解(入门)及快速使用 一.简介: hsql数据库是一款纯Java编写的免费数据库,许可是BSD-style的协议,如果你是使用Java编程的话,不凡考虑一下使用它,相对其 他数据库 ...

  8. Openharmony应用NAPI详解--基础篇

    NAPI是什么? 简单点理解就是在Openharmony里,实现上层js或ets应用与底层C/C++之间交互的框架. Openharmony里的官方解释:NAPI(Native API)组件是一套对外 ...

  9. Openharmony应用NAPI详解--进阶篇1

    NAPI面向C++的异步接口 3.C++实现NAPI异步接口需要做到三步 同步返回结果给js/ets调用者 另起线程完成异步操作 通过回调(callback)或Promise将异步操作结果返回 4.异 ...

最新文章

  1. 网络工程师,不需要学Linux?
  2. Javascript模块化编程(一):模块的写法
  3. memory matlab,memory – 在MATLAB中处理大量结构
  4. NPS cisco 802.1x window7 实现认证接入网络
  5. 常见排序算法详解 (收藏!)
  6. 前端传递json,后端应该怎样接收呢?
  7. php 将字符串打乱,PHP内部实现打乱字符串顺序函数str_shuffle的方法
  8. 如何理解nextTick函数
  9. hashmap和hashtable,arraylist和vector的区别
  10. (博主可帮找错)Servlet.service() for servlet [dispatcherServlet] path [] threw exception feign.Feig,可截图私聊博主
  11. blob类型视频测试(blob加密视频源地址)
  12. 两种MBR分区表恢复方法
  13. win10网络计算机显示不全,win10系统局域网显示计算机设备不完全的解决方法
  14. python实现时间序列预处理
  15. 解决win10通过KMS激活的出现浏览器主页被修改为hao.qquu.com问题
  16. 大一第一学期期末C语言程序设计笔记(一)
  17. 关于密室逃脱的最终解决方案。
  18. oracle系统开发规范,SQL编写规范与优化(适用于Oracle).ppt
  19. c语言取位,C语言位操作
  20. 汉语字典API接口,免费好用

热门文章

  1. sklearn-机器学习笔记
  2. 2021-2025年中国工业锅炉行业市场供需与战略研究报告
  3. Jquery动画2.0
  4. 显卡报价,一夜闪崩 35%
  5. 学生专用计算机怎么发出声音,计算机技巧-如何使显示器的内置扬声器发出声音...
  6. FW:Use Log4XX for Logging
  7. 《离散数学》每章内容及其重点梳理
  8. 俞敏洪:大学生必知的17条法则
  9. MATLAB—离散一元、二元、多元函数求导求梯度(二维、三维、多维空间)(diff和gradient)
  10. Rosenfeld细化算法 matlab(速度超慢)