基本規(guī)范
- 推薦使用 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的處理優(yōu)先順序為 registerTypeAdapter() > 注解 > 內置TypeAdapter 尖奔,在注冊指定序列化處理器時,Gson注解等內置自動序列化系統(tǒng)將失效(控制權由自定義處理器掌控)穷当。
參考:
關于 null 的支持
默認狀態(tài)下提茁,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();
...
使用內置的方案篩選非序列化字段
默認狀態(tài)下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中不可執(zhí)行的 Json(在前綴插入一些特殊字符) -
disableHtmlEscaping()
:禁用Html自動轉義 -
setPrettyPrinting()
:以可讀格式輸出裳仆,默認序列化Json不包含空格,使用可讀格式輸出時將激活內置的JsonPrintFormatter孤钦,生成添加額外空格縮進排版的Json字符串(格式不可自定義) -
serializeSpecialFloatingPointValues()
:允許序列化特殊浮點標記值,如 NAN纯丸、Infinity偏形、-Infinity -
enableComplexMapKeySerialization()
:允許序列化復合型key(如一個自定義對象等)