一、概述
Gson 是一个 Java 库,可用于将 Java 对象转换为其 JSON 表示形式。它还可用于将 JSON 字符串转换为等效的 Java 对象。
Gson 可以使用任意 Java 对象,包括您没有源代码的预先存在的对象。
二、Gson的目标
- 提供易于使用的机制,如toString()和构造函数(工厂方法),将Java转换为JSON,反之亦然
- 允许将预先存在的不可修改对象转换为JSON和从JSON转换
- 允许对象的自定义表达
- 支持任意复杂的对象
- 生成紧凑可读的JSON输出
三、Gson性能和可扩展性
- 字符串:超过 25MB 的反序列化字符串没有任何问题(请参阅中的方法
disabled_testStringDeserializationPerformance
PerformanceTest
) - 大型馆藏:
- 序列化了 1 万个对象的集合(请参阅中的方法
disabled_testLargeCollectionSerialization
PerformanceTest
) - 反序列化了包含 87,000 个对象的集合(请参阅
disabled_testLargeCollectionDeserialization
PerformanceTest
)
- 序列化了 1 万个对象的集合(请参阅中的方法
- Gson 1.4 将字节数组和集合的反序列化限制从 11KB 提高到 80MB 以上。
注意:删除disabled_前缀以运行这些测试。我们使用这个前缀来防止每次运行JUnit测试时都运行这些测试。
四、使用 Gson
要使用的主要类是Gson,您可以通过调用new Gson()来创建它。还有一个类GsonBuilder可用,可用于创建具有各种设置(如版本控制等)的Gson实例。
Gson实例在调用JSON操作时不维护任何状态。因此,您可以自由地为多个JSON序列化和反序列化操作重用同一个对象。
五、将 Gson 与 Maven 一起使用
要将 Gson 与 Maven2/3 一起使用,您可以通过添加以下依赖项来使用 Maven Central 中提供的 Gson 版本:
<dependencies>
<!-- Gson: Java to JSON conversion -->
<dependency>
<groupId>com.google.code.gson</groupId>
<artifactId>gson</artifactId>
<version>2.10.1</version>
<scope>compile</scope>
</dependency>
</dependencies>
示例
// Serialization
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]
// Deserialization
int i = gson.fromJson("1", int.class);
Integer intObj = gson.fromJson("1", Integer.class);
Long longObj = gson.fromJson("1", Long.class);
Boolean boolObj = gson.fromJson("false", Boolean.class);
String str = gson.fromJson("\"abc\"", String.class);
String[] strArray = gson.fromJson("[\"abc\"]", String[].class);
对象示例
class BagOfPrimitives {
private int value1 = 1;
private String value2 = "abc";
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 序列化或反序列化中。
- 此实现正确处理空值。
- 序列化时,输出中省略空字段。
- 反序列化时,JSON 中缺少条目会导致将对象中的相应字段设置为其默认值:对于对象类型为 null,对于数值类型为 zero,对于布尔值为 false。
- 如果字段是合成字段,则会忽略该字段,并且不会包含在 JSON 序列化或反序列化中。
- 与内部类中的外部类对应的字段将被忽略,并且不包括在序列化或反序列化中。
- 匿名类和本地类被排除在外。它们将被序列化为JSON null,当反序列化时,它们的JSON值将被忽略并返回null。将类转换为静态嵌套类,以启用它们的序列化和反序列化。
六、嵌套类(包括内部类)
Gson 可以很容易地序列化静态嵌套类。
Gson 还可以反序列化静态嵌套类。但是,Gson 不能自动反序列化纯内部类,因为它们的 no-args 构造函数还需要对包含对象的引用,而该对象在反序列化时不可用。您可以通过使内部类成为静态或为其提供自定义 InstanceCreator 来解决此问题。下面是一个示例:
public class A {
public String a;
class B {
public String b;
public B() {
// No args constructor for B
}
}
}
注意:上述 B 类不能(默认情况下)使用 Gson 进行序列化。
Gson无法将{“b”:“abc”}反序列化为b的实例,因为类b是内部类。如果它被定义为静态类B,那么Gson将能够反序列化该字符串。另一个解决方案是为B编写一个自定义实例创建者。
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"};
// 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);
// ==> ints2 will be same as ints
八、集合示例
Gson gson = new Gson();
Collection<Integer> ints = Arrays.asList(1,2,3,4,5);
// Serialization
String json = gson.toJson(ints); // ==> json is [1,2,3,4,5]
// Deserialization
TypeToken<Collection<Integer>> collectionType = new TypeToken<Collection<Integer>>(){};
// Note: For older Gson versions it is necessary to use `collectionType.getType()` as argument below,
// this is however not type-safe and care must be taken to specify the correct type for the local variable
Collection<Integer> ints2 = gson.fromJson(json, collectionType);
// ==> ints2 is same as ints
相当可怕:请注意我们如何定义集合的类型。 不幸的是,在Java中没有办法解决这个问题。
集合限制
Gson 可以序列化任意对象的集合,但不能从中反序列化,因为用户无法指示结果对象的类型。相反,在反序列化时,集合必须是特定的泛型类型。 这是有道理的,并且在遵循良好的 Java 编码实践时很少成为问题。