Gson的github文档翻译

Overview-概述

Gson is a Java library that can be used to convert Java Objects into their JSON representation. It can also be used to convert a JSON string to an equivalent Java object.

Gson是一个用于将java对象转换为json表示的java库。他也可以用于将json字符串转换为等效的java对象。

Gson can work with arbitrary Java objects including pre-existing objects that you do not have source code of.

Gson 可以处理任意 Java 对象,包括您没有源代码的预先存在的对象。

Goals for Gson -Gson 的目标

  • Provide easy to use mechanisms like toString() and constructor (factory method) to convert Java to JSON and vice-versa -提供易于使用的机制,如toString()构造函数(工厂方法)将 Java 转换为 JSON,反之亦然
  • Allow pre-existing unmodifiable objects to be converted to and from JSON -允许预先存在的不可修改对象与 JSON 相互转换
  • Allow custom representations for objects -允许对象的自定义表示
  • Support arbitrarily complex objects -支持任意复杂的对象
  • Generate compact and readable JSON output -生成紧凑且可读的 JSON 输出

Gson Performance and Scalability -Gson 性能和可扩展性

Here are some metrics that we obtained on a desktop (dual opteron, 8GB RAM, 64-bit Ubuntu) running lots of other things along-with the tests. You can rerun these tests by using the class PerformanceTest.

  • Strings: Deserialized strings of over 25MB without any problems (see disabled_testStringDeserializationPerformance method in PerformanceTest)
  • Large collections:
    • Serialized a collection of 1.4 million objects (see disabled_testLargeCollectionSerialization method in PerformanceTest)
    • Deserialized a collection of 87,000 objects (see disabled_testLargeCollectionDeserialization in PerformanceTest)
  • Gson 1.4 raised the deserialization limit for byte arrays and collection to over 11MB from 80KB.

Note: Delete the disabled_ prefix to run these tests. We use this prefix to prevent running these tests every time we run JUnit tests.

Gson Users

Gson was originally created for use inside Google where it is currently used in a number of projects. It is now used by a number of public projects and companies.

Using Gson -使用 Gson

The primary class to use is Gson which you can just create by calling new Gson(). There is also a class GsonBuilder available that can be used to create a Gson instance with various settings like version control and so on.

要使用的主要类是Gson您可以通过调用创建的类new Gson()。还有一个GsonBuilder可用的类可用于创建具有各种设置(如版本控制等)的 Gson 实例。

The Gson instance does not maintain any state while invoking Json operations. So, you are free to reuse the same object for multiple Json serialization and deserialization operations.

Gson 实例在调用 Json 操作时不维护任何状态。因此,您可以自由地为多个 Json 序列化和反序列化操作重用同一个对象。

Using Gson with Gradle/Android -在 Gradle/Android 中使用 Gson

1
2
3
dependencies {
implementation 'com.google.code.gson:gson:2.8.9'
}

Using Gson with Maven -在 Maven 中使用 Gson

To use Gson with Maven2/3, you can use the Gson version available in Maven Central by adding the following dependency:

要将 Gson 与 Maven2/3 一起使用,您可以通过添加以下依赖项来使用 Maven Central 中可用的 Gson 版本:

1
2
3
4
5
6
7
8
9
<dependencies>
<!-- Gson: Java to Json conversion -->
<dependency>
<groupId>com.google.code.gson</groupId>
<artifactId>gson</artifactId>
<version>2.8.9</version>
<scope>compile</scope>
</dependency>
</dependencies>

That is it, now your maven project is Gson enabled.

现在您的 Maven 项目启用了 Gson。

Primitives Examples -基本类型示例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
// 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 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);

Object Examples -对象示例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
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"}

Note that you can not serialize objects with circular references since that will result in infinite recursion.

请注意,您不能使用循环引用序列化对象,因为这会导致无限递归。

1
2
3
// Deserialization
BagOfPrimitives obj2 = gson.fromJson(json, BagOfPrimitives.class);
// ==> obj2 is just like obj

Finer Points with Objects -更精细的点与对象

  • It is perfectly fine (and recommended) to use private fields.使用私有字段非常好(并且推荐)。
  • There is no need to use any annotations to indicate a field is to be included for serialization and deserialization. All fields in the current class (and from all super classes) are included by default.不需要使用任何注释来指示要包含的字段以进行序列化和反序列化。默认情况下包含当前类(以及所有超类)中的所有字段。
  • If a field is marked transient, (by default) it is ignored and not included in the JSON serialization or deserialization.如果字段被标记为瞬态,(默认情况下)它将被忽略并且不包含在 JSON 序列化或反序列化中。
  • This implementation handles nulls correctly.此实现正确处理空值。
    • While serializing, a null field is omitted from the output.序列化时,输出中会省略空字段。
    • While deserializing, a missing entry in JSON results in setting the corresponding field in the object to its default value: null for object types, zero for numeric types, and false for booleans.反序列化时,JSON 中缺少条目会导致将对象中的相应字段设置为其默认值:对象类型为 null,数字类型为零,布尔值为 false。
  • If a field is synthetic, it is ignored and not included in JSON serialization or deserialization.如果一个字段是合成的,它将被忽略并且不包含在 JSON 序列化或反序列化中。
  • Fields corresponding to the outer classes in inner classes, anonymous classes, and local classes are ignored and not included in serialization or deserialization.内部类、匿名类和本地类中对应于外部类的字段将被忽略,不包括在序列化或反序列化中

Nested Classes (including Inner Classes)嵌套类(包括内部类)

Gson can serialize static nested classes quite easily.

Gson 可以很容易地序列化静态嵌套类。

Gson can also deserialize static nested classes. However, Gson can not automatically deserialize the pure inner classes since their no-args constructor also need a reference to the containing Object which is not available at the time of deserialization. You can address this problem by either making the inner class static or by providing a custom InstanceCreator for it. Here is an example:

Gson 还可以反序列化静态嵌套类。但是,Gson不能自动反序列化纯内部类,因为它们的无参数构造函数还需要对反序列化时不可用的包含对象的引用。您可以通过将内部类设为静态或为其提供自定义 InstanceCreator 来解决此问题。下面是一个例子:

1
2
3
4
5
6
7
8
9
10
11
12
public class A { 
public String a;

class B {

public String b;

public B() {
// No args constructor for B
}
}
}

NOTE: The above class B can not (by default) be serialized with Gson.

注意:上面的 B 类不能(默认情况下)用 Gson 序列化。

Gson can not deserialize {"b":"abc"} into an instance of B since the class B is an inner class. If it was defined as static class B then Gson would have been able to deserialize the string. Another solution is to write a custom instance creator for B.

Gson 无法反序列{"b":"abc"}化为 B 的实例,因为 B 类是内部类。如果它被定义为静态 B 类,那么 Gson 将能够反序列化字符串。另一种解决方案是为 B 编写自定义实例创建者。

1
2
3
4
5
6
7
8
9
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();
}
}

The above is possible, but not recommended.以上是可以的,但不推荐。

Array Examples数组示例

1
2
3
4
5
6
7
8
9
10
11
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

We also support multi-dimensional arrays, with arbitrarily complex element types.

我们还支持具有任意复杂元素类型的多维数组。

Collections Examples集合示例

1
2
3
4
5
6
7
8
9
10
Gson gson = new Gson();
Collection<Integer> ints = Lists.immutableList(1,2,3,4,5);

// Serialization
String json = gson.toJson(ints); // ==> json is [1,2,3,4,5]

// Deserialization
Type collectionType = new TypeToken<Collection<Integer>>(){}.getType();
Collection<Integer> ints2 = gson.fromJson(json, collectionType);
// ==> ints2 is same as ints

Fairly hideous: note how we define the type of collection. Unfortunately, there is no way to get around this in Java.

相当可怕:注意我们如何定义集合的类型。不幸的是,在 Java 中没有办法解决这个问题。

Collections Limitations集合限制

Gson can serialize collection of arbitrary objects but can not deserialize from it, because there is no way for the user to indicate the type of the resulting object. Instead, while deserializing, the Collection must be of a specific, generic type. This makes sense, and is rarely a problem when following good Java coding practices.

Gson 可以序列化任意对象的集合,但不能反序列化,因为用户无法指示结果对象的类型。相反,在反序列化时,集合必须是特定的泛型类型。这是有道理的,并且在遵循良好的 Java 编码实践时很少会成为问题。

Serializing and Deserializing Generic Types

When you call toJson(obj), Gson calls obj.getClass() to get information on the fields to serialize. Similarly, you can typically pass MyClass.class object in the fromJson(json, MyClass.class) method. This works fine if the object is a non-generic type. However, if the object is of a generic type, then the Generic type information is lost because of Java Type Erasure. Here is an example illustrating the point:

当您调用 时toJson(obj),Gson 会调用obj.getClass()以获取有关要序列化的字段的信息。同样,您通常可以MyClass.classfromJson(json, MyClass.class)方法中传递对象。如果对象是非泛型类型,这可以正常工作。但是,如果对象是泛型类型,那么由于 Java 类型擦除,泛型类型信息将丢失。这是一个说明这一点的例子:

1
2
3
4
5
6
7
8
class Foo<T> {
T value;
}
Gson gson = new Gson();
Foo<Bar> foo = new Foo<Bar>();
gson.toJson(foo); // May not serialize foo.value correctly

gson.fromJson(json, foo.getClass()); // Fails to deserialize foo.value as Bar

The above code fails to interpret value as type Bar because Gson invokes foo.getClass() to get its class information, but this method returns a raw class, Foo.class. This means that Gson has no way of knowing that this is an object of type Foo<Bar>, and not just plain Foo.

上面的代码无法将 value 解释为 Bar 类型,因为 Gson 调用foo.getClass()以获取其类信息,但此方法返回一个原始类Foo.class. 这意味着 Gson 无法知道这是一个类型的对象Foo<Bar>,而不仅仅是普通的Foo

You can solve this problem by specifying the correct parameterized type for your generic type. You can do this by using the TypeToken class.

您可以通过为泛型类型指定正确的参数化类型来解决此问题。您可以通过使用TypeToken该类来做到这一点。

1
2
3
4
Type fooType = new TypeToken<Foo<Bar>>() {}.getType();
gson.toJson(foo, fooType);

gson.fromJson(json, fooType);

The idiom used to get fooType actually defines an anonymous local inner class containing a method getType() that returns the fully parameterized type.

用于 get 的习惯用法fooType实际上定义了一个匿名本地内部类,其中包含一个getType()返回完全参数化类型的方法。

Serializing and Deserializing Collection with Objects of Arbitrary Types使用任意类型的对象序列化和反序列化集合

Sometimes you are dealing with JSON array that contains mixed types. For example: ['hello',5,{name:'GREETINGS',source:'guest'}]

有时您正在处理包含混合类型的 JSON 数组。例如: [‘hello’,5,{name:’GREETINGS’,source:’guest’}]

The equivalent Collection containing this is:

Collection包含此内容的等效项是:

1
2
3
4
Collection collection = new ArrayList();
collection.add("hello");
collection.add(5);
collection.add(new Event("GREETINGS", "guest"));

where the Event class is defined as:

其中Event类定义为:

1
2
3
4
5
6
7
8
class Event {
private String name;
private String source;
private Event(String name, String source) {
this.name = name;
this.source = source;
}
}

You can serialize the collection with Gson without doing anything specific: toJson(collection) would write out the desired output.

您可以使用 Gson 序列化集合,而无需执行任何特定操作:toJson(collection)将写出所需的输出。

However, deserialization with fromJson(json, Collection.class) will not work since Gson has no way of knowing how to map the input to the types. Gson requires that you provide a genericised version of collection type in fromJson(). So, you have three options:

但是,反序列化fromJson(json, Collection.class)不会起作用,因为 Gson 无法知道如何将输入映射到类型。Gson 要求您在fromJson(). 所以,你有三个选择:

  1. Use Gson’s parser API (low-level streaming parser or the DOM parser JsonParser) to parse the array elements and then use Gson.fromJson() on each of the array elements.This is the preferred approach. Here is an example that demonstrates how to do this.使用 Gson 的解析器 API(低级流解析器或 DOM 解析器 JsonParser)解析数组元素,然后Gson.fromJson()在每个数组元素上使用。这是首选方法。这是一个演示如何执行此操作的示例
  2. Register a type adapter for Collection.class that looks at each of the array members and maps them to appropriate objects. The disadvantage of this approach is that it will screw up deserialization of other collection types in Gson.注册一个类型适配器,用于Collection.class查看每个数组成员并将它们映射到适当的对象。这种方法的缺点是它会搞砸 Gson 中其他集合类型的反序列化。
  3. Register a type adapter for MyCollectionMemberType and use fromJson() with Collection<MyCollectionMemberType>.注册一个类型的适配器MyCollectionMemberType和使用fromJson()Collection<MyCollectionMemberType>

This approach is practical only if the array appears as a top-level element or if you can change the field type holding the collection to be of type Collection<MyCollectionMemberType>.

仅当数组显示为顶级元素或者您可以将保存集合的字段类型更改为 type 时,此方法才实用Collection<MyCollectionMemberType>

Built-in Serializers and Deserializers内置序列化器和反序列化器

Gson has built-in serializers and deserializers for commonly used classes whose default representation may be inappropriate, for instance

例如,Gson 为常用类内置了序列化器和反序列化器,这些类的默认表示可能不合适

  • java.net.URL to match it with strings like "https://github.com/google/gson/" 翻译:java.net.URL将它与字符串匹配https://github.com/google/gson/"``
  • java.net.URI to match it with strings like "/google/gson/" 翻译:java.net.URI将它与字符串匹配“/google/gson/“``

For many more, see the internal class TypeAdapters.

有关更多信息,请参阅内部类TypeAdapters

You can also find source code for some commonly used classes such as JodaTime at this page.

您还可以在此页面找到一些常用类的源代码,例如 JodaTime 。

Custom Serialization and Deserialization自定义序列化和反序列化

Sometimes default representation is not what you want. This is often the case when dealing with library classes (DateTime, etc). Gson allows you to register your own custom serializers and deserializers. This is done by defining two parts:

有时默认表示不是您想要的。在处理库类(DateTime 等)时,通常就是这种情况。Gson 允许您注册自己的自定义序列化器和反序列化器。这是通过定义两个部分来完成的:

  • Json Serializers: Need to define custom serialization for an object需要为对象定义自定义序列化
  • Json Deserializers: Needed to define custom deserialization for a type需要为类型定义自定义反序列化
  • Instance Creators: Not needed if no-args constructor is available or a deserializer is registered如果无参数构造函数可用或注册了反序列化器,则不需要
1
2
3
4
5
GsonBuilder gson = new GsonBuilder();
gson.registerTypeAdapter(MyType2.class, new MyTypeAdapter());
gson.registerTypeAdapter(MyType.class, new MySerializer());
gson.registerTypeAdapter(MyType.class, new MyDeserializer());
gson.registerTypeAdapter(MyType.class, new MyInstanceCreator());

registerTypeAdapter call checks if the type adapter implements more than one of these interfaces and register it for all of them.

registerTypeAdapter call 检查类型适配器是否实现了多个这些接口并为所有这些接口注册它。

Writing a Serializer 编写序列化程序

Here is an example of how to write a custom serializer for JodaTime DateTime class.

以下是如何为 JodaTimeDateTime类编写自定义序列化程序的示例。

1
2
3
4
5
private class DateTimeSerializer implements JsonSerializer<DateTime> {
public JsonElement serialize(DateTime src, Type typeOfSrc, JsonSerializationContext context) {
return new JsonPrimitive(src.toString());
}
}

Gson calls serialize() when it runs into a DateTime object during serialization.

Gson在序列化过程中serialize()遇到DateTime对象时调用。

Writing a Deserializer编写反序列化器

Here is an example of how to write a custom deserializer for JodaTime DateTime class.

以下是如何为 JodaTime DateTime 类编写自定义反序列化器的示例。

1
2
3
4
5
6
private class DateTimeDeserializer implements JsonDeserializer<DateTime> {
public DateTime deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context)
throws JsonParseException {
return new DateTime(json.getAsJsonPrimitive().getAsString());
}
}

Gson calls deserialize when it needs to deserialize a JSON string fragment into a DateTime object

Gsondeserialize在需要将 JSON 字符串片段反序列化为 DateTime 对象时调用

Finer points with Serializers and Deserializers序列化器和反序列化器的精髓****

Often you want to register a single handler for all generic types corresponding to a raw type

通常,您希望为与原始类型对应的所有泛型类型注册单个处理程序

  • For example, suppose you have an Id class for id representation/translation (i.e. an internal vs. external representation).例如,假设您有一个Id用于 id 表示/翻译的类(即内部与外部表示)。
  • Idtype that has same serialization for all generic types 翻译:Id<T> 对所有泛型类型具有相同序列化的类型
    • Essentially write out the id value本质上写出id值
  • Deserialization is very similar but not exactly the same反序列化非常相似但不完全相同
    • Need to call new Id(Class<T>, String) which returns an instance of Id<T> 需要调用new Id(Class<T>, String)它返回一个实例Id<T>

Gson supports registering a single handler for this. You can also register a specific handler for a specific generic type (say Id<RequiresSpecialHandling> needed special handling). The Type parameter for the toJson() and fromJson() contains the generic type information to help you write a single handler for all generic types corresponding to the same raw type.

Gson 支持为此注册单个处理程序。您还可以为特定的泛型类型注册特定的处理程序(比如Id<RequiresSpecialHandling>需要特殊处理)。在Type该参数toJson()fromJson()包含的通用类型的信息来帮助你编写对应于同一原始类型的所有泛型类型单一的处理程序

Writing an Instance Creator编写实例创建器

While deserializing an Object, Gson needs to create a default instance of the class. Well-behaved classes that are meant for serialization and deserialization should have a no-argument constructor.

在反序列化对象时,Gson 需要创建类的默认实例。用于序列化和反序列化的行为良好的类应该有一个无参数的构造函数。

  • Doesn’t matter whether public or private不管是公有私

Typically, Instance Creators are needed when you are dealing with a library class that does NOT define a no-argument constructor

通常,当您处理未定义无参数构造函数的库类时,需要 Instance Creators

Instance Creator Example实例创建者示例****

1
2
3
4
5
private class MoneyInstanceCreator implements InstanceCreator<Money> {
public Money createInstance(Type type) {
return new Money("1000000", CurrencyCode.USD);
}
}

Type could be of a corresponding generic type类型可以是相应的泛型类型

  • Very useful to invoke constructors which need specific generic type information调用需要特定泛型类型信息的构造函数非常有用
  • 例如,如果Id类存储正在为其创建 Id 的类
  • For example, if the Id class stores the class for which the Id is being created

InstanceCreator for a Parameterized Type参数化类型的 InstanceCreator

Sometimes the type that you are trying to instantiate is a parameterized type. Generally, this is not a problem since the actual instance is of raw type. Here is an example:

有时,您尝试实例化的类型是参数化类型。通常,这不是问题,因为实际实例是原始类型。下面是一个例子:

1
2
3
4
5
6
7
8
9
10
class MyList<T> extends ArrayList<T> {
}

class MyListInstanceCreator implements InstanceCreator<MyList<?>> {
@SuppressWarnings("unchecked")
public MyList<?> createInstance(Type type) {
// No need to use a parameterized list since the actual instance will have the raw type anyway.
return new MyList();
}
}

However, sometimes you do need to create instance based on the actual parameterized type. In this case, you can use the type parameter being passed to the createInstance method. Here is an example:

但是,有时您确实需要根据实际参数化类型创建实例。在这种情况下,您可以使用传递给createInstance方法的类型参数。下面是一个例子:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
public class Id<T> {
private final Class<T> classOfId;
private final long value;
public Id(Class<T> classOfId, long value) {
this.classOfId = classOfId;
this.value = value;
}
}

class IdInstanceCreator implements InstanceCreator<Id<?>> {
public Id<?> createInstance(Type type) {
Type[] typeParameters = ((ParameterizedType)type).getActualTypeArguments();
Type idType = typeParameters[0]; // Id has only one parameterized type T
return new Id((Class)idType, 0L);
}
}

In the above example, an instance of the Id class can not be created without actually passing in the actual type for the parameterized type. We solve this problem by using the passed method parameter, type. The type object in this case is the Java parameterized type representation of Id<Foo> where the actual instance should be bound to Id<Foo>. Since Id class has just one parameterized type parameter, T, we use the zeroth element of the type array returned by getActualTypeArgument() which will hold Foo.class in this case.

在上面的例子中,如果没有实际传递参数化类型的实际类型,就无法创建 Id 类的实例。我们通过使用传递的方法参数来解决这个问题,typetype在这种情况下,对象是Id<Foo>实际实例应该绑定到的位置的Java 参数化类型表示Id<Foo>。由于Idclass 只有一个参数化类型参数 ,T我们使用返回的类型数组的第零个元素,在这种情况下getActualTypeArgument()它将保持不变Foo.class

Compact Vs. Pretty Printing for JSON Output Format紧凑型对比 JSON 输出格式的漂亮打印

The default JSON output that is provided by Gson is a compact JSON format. This means that there will not be any whitespace in the output JSON structure. Therefore, there will be no whitespace between field names and its value, object fields, and objects within arrays in the JSON output. As well, “null” fields will be ignored in the output (NOTE: null values will still be included in collections/arrays of objects). See the Null Object Support section for information on configure Gson to output all null values.

Gson 提供的默认 JSON 输出是紧凑的 JSON 格式。这意味着输出 JSON 结构中不会有任何空格。因此,JSON 输出中的字段名称及其值、对象字段和数组中的对象之间不会有空格。同样,输出中的“空”字段将被忽略(注意:空值仍将包含在对象的集合/数组中)。有关配置 Gson 以输出所有空值的信息,请参阅空对象支持部分。If you would like to use the Pretty Print feature, you must configure your Gson instance using the GsonBuilder. The JsonFormatter is not exposed through our public API, so the client is unable to configure the default print settings/margins for the JSON output. For now, we only provide a default JsonPrintFormatter that has default line length of 80 character, 2 character indentation, and 4 character right margin.

如果您想使用漂亮打印功能,您必须Gson使用GsonBuilder. 在JsonFormatter没有通过我们的公共API公开,所以客户端无法配置默认打印设置/利润率为JSON输出。目前,我们仅提供JsonPrintFormatter默认行长度为 80 个字符、2 个字符缩进和 4 个字符右边距的默认值。

The following is an example shows how to configure a Gson instance to use the default JsonPrintFormatter instead of the JsonCompactFormatter:

以下示例显示了如何将Gson实例配置为使用默认值JsonPrintFormatter而不是JsonCompactFormatter

1
2
Gson gson = new GsonBuilder().setPrettyPrinting().create();
String jsonOutput = gson.toJson(someObject);

Null Object Support空对象支持

The default behaviour that is implemented in Gson is that null object fields are ignored. This allows for a more compact output format; however, the client must define a default value for these fields as the JSON format is converted back into its Java form.

Gson 中实现的默认行为null是忽略对象字段。这允许更紧凑的输出格式;但是,客户端必须为这些字段定义默认值,因为 JSON 格式会转换回其 Java 格式。

Here’s how you would configure a Gson instance to output null:

以下是将Gson实例配置为输出 null 的方法:

1
Gson gson = new GsonBuilder().serializeNulls().create();

NOTE: when serializing nulls with Gson, it will add a JsonNull element to the JsonElement structure. Therefore, this object can be used in custom serialization/deserialization.

注意:当null使用 Gson序列化s 时,它会JsonNullJsonElement结构中添加一个元素。因此,该对象可用于自定义序列化/反序列化。

Here’s an example:下面是一个例子:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
public class Foo {
private final String s;
private final int i;

public Foo() {
this(null, 5);
}

public Foo(String s, int i) {
this.s = s;
this.i = i;
}
}

Gson gson = new GsonBuilder().serializeNulls().create();
Foo foo = new Foo();
String json = gson.toJson(foo);
System.out.println(json);

json = gson.toJson(null);
System.out.println(json);

The output is:

1
2
{"s":null,"i":5}
null

Versioning Support版本支持

Multiple versions of the same object can be maintained by using @Since annotation. This annotation can be used on Classes, Fields and, in a future release, Methods. In order to leverage this feature, you must configure your Gson instance to ignore any field/object that is greater than some version number. If no version is set on the Gson instance then it will serialize and deserialize all fields and classes regardless of the version.

可以使用@Since注解维护同一对象的多个版本。该注解可用于类、字段以及未来版本中的方法。为了利用此功能,您必须将Gson实例配置为忽略大于某个版本号的任何字段/对象。如果没有在Gson实例上设置版本,那么无论版本如何,它都会序列化和反序列化所有字段和类。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
public class VersionedClass {
@Since(1.1) private final String newerField;
@Since(1.0) private final String newField;
private final String field;

public VersionedClass() {
this.newerField = "newer";
this.newField = "new";
this.field = "old";
}
}

VersionedClass versionedObject = new VersionedClass();
Gson gson = new GsonBuilder().setVersion(1.0).create();
String jsonOutput = gson.toJson(versionedObject);
System.out.println(jsonOutput);
System.out.println();

gson = new Gson();
jsonOutput = gson.toJson(versionedObject);
System.out.println(jsonOutput);

The output is:

1
2
3
{"newField":"new","field":"old"}

{"newerField":"newer","newField":"new","field":"old"}

Excluding Fields From Serialization and Deserialization从序列化和反序列化中排除字段

Gson supports numerous mechanisms for excluding top-level classes, fields and field types. Below are pluggable mechanisms that allow field and class exclusion. If none of the below mechanisms satisfy your needs then you can always use custom serializers and deserializers.

Gson 支持多种机制来排除顶级类、字段和字段类型。下面是允许字段和类排除的可插入机制。如果以下机制都不能满足您的需求,那么您始终可以使用自定义序列化器和反序列化器

Java Modifier ExclusionJava 修饰符排除

By default, if you mark a field as transient, it will be excluded. As well, if a field is marked as static then by default it will be excluded. If you want to include some transient fields then you can do the following:

默认情况下,如果您将字段标记为transient,它将被排除在外。同样,如果一个字段被标记为staticthen 默认情况下它将被排除。如果要包含一些临时字段,则可以执行以下操作:

1
2
3
4
import java.lang.reflect.Modifier;
Gson gson = new GsonBuilder()
.excludeFieldsWithModifiers(Modifier.STATIC)
.create();

NOTE: you can give any number of the Modifier constants to the excludeFieldsWithModifiers method. For example:

注意:您可以Modifier为该excludeFieldsWithModifiers方法提供任意数量的常量。例如:

1
2
3
Gson gson = new GsonBuilder()
.excludeFieldsWithModifiers(Modifier.STATIC, Modifier.TRANSIENT, Modifier.VOLATILE)
.create();

Gson’s @Expose

This feature provides a way where you can mark certain fields of your objects to be excluded for consideration for serialization and deserialization to JSON. To use this annotation, you must create Gson by using new GsonBuilder().excludeFieldsWithoutExposeAnnotation().create(). The Gson instance created will exclude all fields in a class that are not marked with @Expose annotation.

此功能提供了一种方法,您可以将对象的某些字段标记为要排除以考虑序列化和反序列化为 JSON。要使用此注解,您必须使用new GsonBuilder().excludeFieldsWithoutExposeAnnotation().create(). 创建的 Gson 实例将排除类中所有没有标注的字段@Expose

User Defined Exclusion Strategies用户定义的排除策略

If the above mechanisms for excluding fields and class type do not work for you then you can always write your own exclusion strategy and plug it into Gson. See the ExclusionStrategy JavaDoc for more information.

如果上述排除字段和类类型的机制对您不起作用,那么您可以随时编写自己的排除策略并将其插入 Gson。有关ExclusionStrategy更多信息,请参阅JavaDoc。

The following example shows how to exclude fields marked with a specific @Foo annotation and excludes top-level types (or declared field type) of class String.

以下示例显示了如何排除标有特定@Foo注释的字段并排除 class 的顶级类型(或声明的字段类型)String

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.FIELD})
public @interface Foo {
// Field tag only annotation
}

public class SampleObjectForTest {
@Foo private final int annotatedField;
private final String stringField;
private final long longField;
private final Class<?> clazzField;

public SampleObjectForTest() {
annotatedField = 5;
stringField = "someDefaultValue";
longField = 1234;
}
}

public class MyExclusionStrategy implements ExclusionStrategy {
private final Class<?> typeToSkip;

private MyExclusionStrategy(Class<?> typeToSkip) {
this.typeToSkip = typeToSkip;
}

public boolean shouldSkipClass(Class<?> clazz) {
return (clazz == typeToSkip);
}

public boolean shouldSkipField(FieldAttributes f) {
return f.getAnnotation(Foo.class) != null;
}
}

public static void main(String[] args) {
Gson gson = new GsonBuilder()
.setExclusionStrategies(new MyExclusionStrategy(String.class))
.serializeNulls()
.create();
SampleObjectForTest src = new SampleObjectForTest();
String json = gson.toJson(src);
System.out.println(json);
}

The output is:

1
{"longField":1234}

JSON Field Naming SupportJSON 字段命名支持

Gson supports some pre-defined field naming policies to convert the standard Java field names (i.e., camel cased names starting with lower case — sampleFieldNameInJava) to a Json field name (i.e., sample_field_name_in_java or SampleFieldNameInJava). See the FieldNamingPolicy class for information on the pre-defined naming policies.

Gson 支持一些预定义的字段命名策略来将标准的 Java 字段名称(即以小写 — 开头的驼峰命名法sampleFieldNameInJava)转换为 Json 字段名称(即,sample_field_name_in_javaor SampleFieldNameInJava)。有关预定义命名策略的信息,请参阅FieldNamingPolicy类。

It also has an annotation based strategy to allows clients to define custom names on a per field basis. Note, that the annotation based strategy has field name validation which will raise “Runtime” exceptions if an invalid field name is provided as the annotation value.

它还具有基于注释的策略,允许客户在每个字段的基础上定义自定义名称。请注意,基于注释的策略具有字段名称验证,如果提供无效的字段名称作为注释值,则会引发“运行时”异常。

The following is an example of how to use both Gson naming policy features:

以下是如何使用 Gson 命名策略功能的示例:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
private class SomeObject {
@SerializedName("custom_naming") private final String someField;
private final String someOtherField;

public SomeObject(String a, String b) {
this.someField = a;
this.someOtherField = b;
}
}

SomeObject someObject = new SomeObject("first", "second");
Gson gson = new GsonBuilder().setFieldNamingPolicy(FieldNamingPolicy.UPPER_CAMEL_CASE).create();
String jsonRepresentation = gson.toJson(someObject);
System.out.println(jsonRepresentation);

The output is:

1
{"custom_naming":"first","SomeOtherField":"second"}

If you have a need for custom naming policy (see this discussion), you can use the @SerializedName annotation.

如果您需要自定义命名策略(请参阅此讨论),您可以使用@SerializedName注释。

Sharing State Across Custom Serializers and Deserializers在自定义序列化器和反序列化器之间共享状态

Sometimes you need to share state across custom serializers/deserializers (see this discussion). You can use the following three strategies to accomplish this:

有时您需要在自定义序列化器/反序列化器之间共享状态(请参阅此讨论)。您可以使用以下三种策略来完成此操作:

  1. Store shared state in static fields -在静态字段中存储共享状态
  2. Declare the serializer/deserializer as inner classes of a parent type, and use the instance fields of parent type to store shared state -将序列化器/反序列化器声明为父类型的内部类,并使用父类型的实例字段来存储共享状态
  3. Use Java ThreadLocal -使用 Java ThreadLocal

1 and 2 are not thread-safe options, but 3 is.

1 和 2 不是线程安全选项,但 3 是。

Streaming

In addition Gson’s object model and data binding, you can use Gson to read from and write to a stream. You can also combine streaming and object model access to get the best of both approaches.

除了 Gson 的对象模型和数据绑定之外,您还可以使用 Gson 读取和写入。您还可以结合流和对象模型访问来充分利用这两种方法。

Issues in Designing Gson

See the Gson design document for a discussion of issues we faced while designing Gson. It also include a comparison of Gson with other Java libraries that can be used for Json conversion.

Future Enhancements to Gson

For the latest list of proposed enhancements or if you’d like to suggest new ones, see the Issues section under the project website.


本博客所有文章除特别声明外,均采用 CC BY-SA 4.0 协议 ,转载请注明出处!