网上很多 Gson 的文章介绍的比较琐碎,于是干脆把 GitHub 上的使用介绍给翻译了出来。
原文地址:https://github.com/google/gson/blob/master/UserGuide.md
Gson 库中最重要的类是 Gson
,你可以通过调用 new Gson()
来创建一个 Gson 对象。同时也提供一个 GsonBuilder
类来创建一个 Gson 对象,这种创建方式允许自定义多种配置信息。
Gson 对象在调用 Json 相关的操作时并不会保存任何状态信息,因此你可以在同一个项目中使用重复使用同一个 Gson 对象来对多个 Json 进行序列化和反序列化操作。
基本示例
// 序列化
Gson gson = new Gson();
gson.toJson(1); // ==> 1
gson.toJson("abcd"); // ==> "abcd"
gson.toJson(new Long(10)); // ==> 10
int[] values = { 1 };
gson.toJson(values); // ==> [1]
// 反序列化
int one = gson.fromJson("1", int.class);
Integer one = gson.fromJson("1", Integer.class);
Long one = gson.fromJson("1", Long.class);
Boolean false = gson.fromJson("false", Boolean.class);
String str = gson.fromJson("\"abc\"", String.class);
String[] anotherStr = gson.fromJson("[\"abc\"]", String[].class);
对象示例
class BagOfPrimitives {
private int value1 = 1;
private String value2 = "abc";
private transient int value3 = 3;
BagOfPrimitives() {
// 无参构造方法
}
}
// 序列化
BagOfPrimitives obj = new BagOfPrimitives();
Gson gson = new Gson();
String json = gson.toJson(obj);
// ==> json is {"value1":1,"value2":"abc"}
注意,你不能序列化一个循环引用,这样会引发无限递归。
// 反序列化
BagOfPrimitives obj2 = gson.fromJson(json, BagOfPrimitives.class);
// ==> obj2 is just like obj
注意事项
- 建议使用 private 修饰属性。
- 不需要使用任何注解来表明一个属性是否应该序列化和反序列化。默认情况下,当前类的所有属性(以及从父类继承的属性)都将被参与序列化和反序列化。
- 如果一个属性被
transient
修饰,默认情况下该属性会被忽略掉,并且不参与 JSON 的序列化和反序列化。 - 上面介绍的实现方式可以正确地处理 null。
- 在序列化的时候,一个值为 null 的字段不会在输出中出现。
- 在反序列化时,JSON 中缺少的条目导致将对象中的相应字段设置为null。
- 如果一个字段被
synthetic
修饰,则该属性会被忽略,并且不参与 JSON 的序列化和反序列化。 - 与内部类,匿名类和局部类中的外部类对应的字段将被忽略,并且不会包含在序列化或反序列化中。
嵌套类(包括内部类)
Gson 可以非常便捷地序列化静态嵌套类。
Gson也可以反序列化静态嵌套类。然而,Gson不能自动反序列化纯内部类,因为它们的无参构造方法也需要一个对象的引用,这在反序列化时是无法获得的。你可以通过将内部类变为静态内部类,或为其提供自定义InstanceCreator来解决此问题。下面举例说明:
public class A {
public String a;
class B {
public String b;
public B() {
// 类 B 的无参构造方法
}
}
}
注意:上面的类 B 默认情况下是无法使用 Gson 来序列化的。
由于类 B 是一个内部类,因此 Gson 无法将 {"b": "abc"}
序列化为一个 B 对象。如果将类 B 定义为静态内部类,则 Gson 就能正确地将这个字符串反序列。另一个解决方法是为类 B 编写一个自定义的 InstanceCreator :
public class InstanceCreatorForB implements InstanceCreator<A.B> {
private final A a;
public InstanceCreatorForB(A a) {
this.a = a;
}
public A.B createInstance(Type type) {
return a.new B();
}
}
这种方法是可行的,但是不建议这么做。
数组
Gson gson = new Gson();
int[] ints = {
1, 2, 3, 4, 5};
String[] strings = {
"abc", "def", "ghi"};
// 序列化
gson.toJson(ints); // ==> [1,2,3,4,5]
gson.toJson(strings); // ==> ["abc", "def", "ghi"]
// 反序列化
int[] ints2 = gson.fromJson("[1,2,3,4