01、前世今生
我叫 Gson,是一款开源的 Java 库,主要用途为序列化 Java 对象为 JSON 字符串,或反序列化 JSON 字符串成 Java 对象。从我的名字上,就可以看得出一些端倪,我并非籍籍无名,我出身贵族,我爸就是 Google,市值富可敌国。
当然了,作为一个聪明人,我是有自知之明的,我在我爸眼里,我并不是最闪耀的那颗星。
我来到这个世上,纯属一次意外,反正我爸是这样对我说的,他总说我是从河边捡回来的,虽然我一直不太相信。对于这件事,我向我妈确认过,她听完笑得合不拢嘴,说我太天真。
长大后,我喜欢四处闯荡,因此结识了不少同行,其中就有 Jackson 和 Fastjson。
说起 Jackson,我总能第一时间想到 MJ,那个被上帝带走的流行天王。Jackson 在 GitHub 上有 6.1k 的 star,虽然他的粉丝数没我多,但作为 Spring Boot 的默认 JSON 解析器,我非常地尊重他。
Fastjson 来自神秘的东方,虽然爆出过一些严重的漏洞,但这并不妨碍他成为最受欢迎的 JSON 解析器,他的粉丝数比我还要多,尽管我已经有超过 18K 的 star。
外人总说我们是竞争对手,但我必须得告诉他们,我们仨的关系,好到就差穿同一条内裤了。
我们各有优势,Jackson 在运行时占用的内存较少,Fastjson 的速度更快,而我,可以处理任意的 Java 对象,甚至在没有源代码的情况下。另外,我对泛型的支持也更加的友好。
02、添加依赖
在使用我的 API 之前,需要先把我添加到项目当中,推荐使用 Maven 和 Gradle 两种形式。
Maven:
<dependency>
<groupId>com.google.code.gson</groupId>
<artifactId>gson</artifactId>
<version>2.8.6</version>
</dependency>
Gradle:
dependencies {
implementation 'com.google.code.gson:gson:2.8.6'
}
PS:Gradle 是一个基于 Apache Ant 和 Apache Maven 概念的项目自动化建构工具。Gradle 构建脚本使用的是 Groovy 或 Kotlin 的特定领域语言来编写的,而不是传统的 XML。
03、性能表现
不是我觉得,是真的,通过大量的测试证明,我在处理 JSON 的时候性能还是很牛逼的。
测试环境:双核,8G 内存,64 位的 Ubuntu 操作系统(以桌面应用为主的 Linux 发行版)
测试结果:
1)在反序列化 25M 以上的字符串时没有出现过任何问题。
2)可以序列化 140 万个对象的集合。
3)可以反序列化包含 87000 个对象的集合。
4)将字节数组和集合的反序列化限制从 80K 提高到 11M 以上。
测试用例我已经帮你写好了,放在 GitHub 上,如果你不相信的话,可以验证一下。
04、使用指南
不是我自吹自擂,是真的,我还是挺好用的,上手难度几乎为零。如果你不相信话,可以来试试。
我有一个女朋友,她的名字和我一样,也叫 Gson,我的主要功能都由她来提供。你可以通过 new Gson() 的这种简单粗暴的方式创建她,也可以打电话给一个叫 GsonBuilder 的老板,让他邮寄一个复刻版过来,真的,我不骗你。
先来看一个序列化的例子。
Gson gson = new Gson();
System.out.println(gson.toJson(18));
System.out.println(gson.toJson("沉默"));
System.out.println(gson.toJson(new Integer(18)));
int[] values = { 18,20 };
System.out.println(gson.toJson(values));
在我女朋友的帮助下,你可以将基本数据类型 int、字符串类型 String、包装器类型 Integer、int 数组等等作为参数,传递给 toJson() 方法,该方法将会返回一个 JSON 形式的字符串。
来看一下输出结果:
18
"沉默"
18
[18,20]
再来看一下反序列化的例子。
Gson gson = new Gson();
int one = gson.fromJson("1", int.class);
Integer two = gson.fromJson("2", Integer.class);
Boolean false1 = gson.fromJson("false", Boolean.class);
String str = gson.fromJson("\"王二\"", String.class);
String[] anotherStr = gson.fromJson("[\"沉默\",\"王二\"]", String[].class);
System.out.println(one);
System.out.println(two);
System.out.println(false1);
System.out.println(str);
System.out.println(Arrays.toString(anotherStr));
toJson() 方法用于序列化,对应的,fromJson() 方法用于反序列化。不过,你需要在反序列化的时候,指定参数的类型,是 int 还是 Integer,是 Boolean 还是 String,或者 String 数组。
来看一下输出结果:
1
2
false
王二
[沉默, 王二]
上面的例子都比较简单,还体现不出来我的威力。
下面,我们来自定义一个类:
public class Writer {
private int age = 18;
private String name = "王二";
private transient int sex = 1;
}
然后,我们来将其序列化:
Writer writer = new Writer();
Gson gson = new Gson();
String json = gson.toJson(writer);
System.out.println(json);
用法和之前一样简单,来看一下输出结果:
{"age":18,"name":"王二"}
1
同样,可以将结果反序列化:
Writer writer1 = gson.fromJson(json, Writer.class);
1
这里有一些注意事项,我需要提醒你。
1)推荐使用 private 修饰字段。
2)不需要使用任何的注解来表明哪些字段需要序列化,哪些字段不需要序列化。默认情况下,包括所有的字段,以及从父类继承过来的字段。
3)如果一个字段被 transient 关键字修饰的话,它将不参与序列化。
4)如果一个字段的值为 null,它不会在序列化后的结果中显示。
5)JSON 中缺少的字段将在反序列化后设置为默认值,引用数据类型的默认值为 null,数字类型的默认值为 0,布尔值默认为 false。
接下来,来看一个序列化集合的例子。
List<String> list =new ArrayList<>();
list.add("好好学习");
list.add("天天向上");
String json = gson.toJson(list);
结果如下所示:
["好好学习","天天向上"]
1
反序列化的时候,也很简单。
List<String> listResult = gson.fromJson(json,List.class);
1
结果如下所示:
[好好学习, 天天向上]