基本规范
- 推荐使用 private 类型,支持使用 final 声明
- 支持 null 值,序列化输出时自动跳过,反序列化时直接返回null
- 支持多维数组、Collection类型
- 支持 URL、URI 的反序列化自动类型转换(也可支持JodaTime转换,参考 JodaTime Type Converter)
- 不需要定义 getter / setter 方法(通过反射设置参数值)
- 不需要带参构造函数,并且无参构造函数不必为 public
- 不必要使用注解标记序列化对象,除非需要指定别名映射
- 当前类及其所有父类的所有字段均视为默认序列化对象
- 序列化、反序列化(如 Collection 等)泛型类型时,需要通过
TypeToken
指定目标泛型的确切类型值 - 反序列化 混合类型数组 时,可参考官方指引:Serializing and Deserializing Collection with Objects of Arbitrary Types
不属于序列化输出范围
- transient 类型字段
- 非 static 嵌套类、内部类型
- 经非序列化方式指定的字段
指定Json字段命名映射
Gson 默认使用类字段名作为序列化、反序列化的 Json 数据字段名。
可通过 @SerializedName(name)
注解指定该字段对应的 Json 字段名,也可以通过添加字段命名内置策略方式改变字段名输出形式。
通过实现 FieldNamingStrategy
接口,可自定义命名映射策略,通过 gsonBuilder.setFieldNamingStrategy(FieldNamingStrategy)
方式进行设定。
// 添加 @SerializedName 注解指定命名
// 可分别通过 value 和 alternate数组 指定序列化、反序列化时有效的字段命名
private class SomeObject {
@SerializedName("custom_naming") private final String someField;
private final String someOtherField;
}
// 添加名字映射策略,这里使用首字母大写驼峰策略
Gson gson = new GsonBuilder()
.setFieldNamingPolicy(FieldNamingPolicy.UPPER_CAMEL_CASE)
.create();
通过 TypeToken 指定泛型类型值
Foo<Bar> foo = new Foo<Bar>();
// 指定泛型的确切类型值
Type fooType = new TypeToken<Foo<Bar>>(){}.getType();
// 泛型序列化、反序列化,传入泛型类型值(序列化过程可不传入,但不保证序列化结果正确性)
gson.toJson(foo, fooType);
gson.fromJson(json, fooType);
Collection类型在序列化时受Gson内部支持,不需要指定泛型类型。
通过 TypeAdapter 彻底自定义序列化、反序列化行为
通过自定义实现 TypeAdapter
或 JsonSerializer
/ JsonDeserializer
接口,指定Json的序列化、反序列化完整逻辑。
其中 TypeAdapter
为低层抽象类,自定义实现从流开始完全接管、控制序列化行为,序列化对象为 JsonWriter
/ JsonReader
,运行效率而言相对较高。
而 JsonSerializer
/ JsonDeserializer
可按需分别指定特定类型值的序列化、反序列化的过程,序列化对象为 JsonElement
。
当目标对象类型不提供无参构造函数时,需要注册一个 InstanceCreator
实现类,用于以无参方式实例化一个目标对象。
- (可选)实现 InstanceCreator 接口,提供以无参方式构造一个默认只能带参构造的目标容器对象
- (可选)实现 JsonSerializer 接口,提供目标对象序列化至JsonElement类型的方法
- (可选)实现 JsonDeserializer 接口,提供JsonElement类型反序列化至目标类型的方法
- (可选)派生 TypeAdapter 子类,提供基于流的序列化、反序列化完整逻辑
GsonBuilder builder = new GsonBuilder();
// 需要时注册一个自定义 InstanceCreator 对象
builder.registerTypeAdapter(MyType.class, new MyInstanceCreator());
// 通过 registerTypeAdapter() 方法指定一个针对特定类型对象的委托序列化、反序列化器
// 第一个class类型参数必须为具体包装类型,可指定为一个泛型
// 使用 registerTypeHierarchyAdapter 则可使用抽象父类作为类型值,但不支持泛型
builder.registerTypeAdapter(String.class, new MySerializer());
builder.registerTypeAdapter(Integer.class, new MyDeserializer());
// 通过派生 TypeAdapter 指定一个针对特定类型对象的委托序列化、反序列化器
// 如果派生的 TypeAdapter 不对null参数值进行特殊处理
// 可简单使用 new MyTypeAdapter().nullSafe() 代替
builder.registerTypeAdapter(MyType2.class, new MyTypeAdapter());
Gson gson = builder.create();
注册使用
JsonSerializer
、JsonDeserializer
、TypeAdapter
、TypeAdapterFactory
等自定义序列化处理器时,对于同一目标类型的(反)序列化以最后一个注册为准。
Gson的处理优先顺序为 registerTypeAdapter() > 注解 > 内置TypeAdapter ,在注册指定序列化处理器时,Gson注解等内置自动序列化系统将失效(控制权由自定义处理器掌控)。
参考:
关于 null 的支持
默认状态下,null 值的对象在序列化 Json 过程中会直接忽略,不输出到 Json 结果,但可通过以下方式简单的启用 null 输出:gsonBuilder.serializeNulls().create()
反序列化时,传入空的Json或null或"null",将直接返回null
输出 Json 效果如:
gson.toJson(stuff) -> {"name":null,"number":5}
gson.toJson(null) -> null
gson.fromJson("", Type.class) -> null
序列化版本支持
可指定某些字段仅在特定版本下实施序列化,比序列化所用 Gson 对象指定版本更高的字段将被忽略。
public class VersionedClass {
// 通过 @Since 和 @Until 注解指定该字段的有效起始版本(包含)、有效到期版本(不包含)
@Since(1.1) private final String newerField;
@Since(1.0) private final String newField;
@Until(2.0) private final String oldField;
private final String field;
}
// 指定 1.0 版本时,序列化输出 Json 不包括 1.1 版本及以上的字段 newerField
// 但包含 2.0 版本以下时可用的字段 oldField
Gson gson = new GsonBuilder().setVersion(1.0).create();
...
// 不指定版本时,版本机制无效,所有字段都将输出到结果 Json
gson = new Gson();
...
使用内置的方案筛选非序列化字段
默认状态下Gson自动排除经 transient 声明的字段。
除此之外,可在 GsonBuilder 中通过以下两种方式添加额外的排除方案:
// 通过 excludeFieldsWithModifiers 指定需要排除的修饰符
Gson gson = new GsonBuilder()
.excludeFieldsWithModifiers(Modifier.STATIC, Modifier.TRANSIENT, Modifier.VOLATILE)
.create();
// 通过 @Expose 注解标记可以序列化的合法字段
// 其中可选分别指定 serialize 和 deserialize 的有效性
// @Expose = @Expose(serialize = true, deserialize = true)
@Expose private final String fieldForOutput;
final String fieldForCacheLocally;
gson = new GsonBuilder()
.excludeFieldsWithoutExposeAnnotation()
.create();
使用自定义方案识别非序列化字段
派生 ExclusionStrategy
子类,覆盖指定方法,以代码逻辑方式判断需要排除的字段类型、注解标记、字段值等特征。
Gson gson = new GsonBuilder()
.setExclusionStrategies(new MyExclusionStrategy(String.class))
.addSerializationExclusionStrategy(ExclusionStrategy)
.addDeserializationExclusionStrategy(ExclusionStrategy)
.create();
参考:
其他可选格式化设置
通过 GsonBuilder
可链式设置多种格式化方案:
-
serializeNulls()
:允许序列化输出 null -
setDateFormat("yyyy-MM-dd")
:设置序列化、反序列化时使用的日期格式 -
disableInnerClassSerialization()
:禁止序列化内部类 -
generateNonExecutableJson()
:生成JS中不可执行的 Json(在前缀插入一些特殊字符) -
disableHtmlEscaping()
:禁用Html自动转义 -
setPrettyPrinting()
:以可读格式输出,默认序列化Json不包含空格,使用可读格式输出时将激活内置的JsonPrintFormatter,生成添加额外空格缩进排版的Json字符串(格式不可自定义) -
serializeSpecialFloatingPointValues()
:允许序列化特殊浮点标记值,如 NAN、Infinity、-Infinity -
enableComplexMapKeySerialization()
:允许序列化复合型key(如一个自定义对象等)