Gson 作為 Java 領域最流行的 JSON 庫之一,其功能遠不止基礎的序列化/反序列化。本文系統梳理 Gson 的進階特性:泛型 TypeToken、集合限制、巢狀類處理、自定義 TypeAdapter/InstanceCreator、Null 安全、版本控制、字段過濾策略、命名策略、線程安全的狀態共享,並給出生產級 NullStringToEmptyAdapterFactory 解決方案。
Gson:無狀態,線程安全,可全局單例復用。GsonBuilder:構建定制實例,建議在啟動階段構建好單例。Gson gson = new Gson();
gson.toJson(1); // "1"
gson.toJson("abcd"); // "\"abcd\""
gson.toJson(new long[]{1,2,3}); // "[1,2,3]"
int[] arr = gson.fromJson("[1,2,3]", int[].class);
痛點: Java 泛型擦除導致運行時丟失類型參數,foo.getClass() 僅返回 Foo.class,無法獲知 Foo<Bar>。
class Foo<T> { T value; }
Foo<Bar> foo = new Foo<Bar>();
gson.toJson(foo); // 可能無法正確序列化 value
gson.fromJson(json, foo.getClass()); // 無法將 value 反序列化為 Bar
// 解決:TypeToken 捕獲完整泛型類型
Type fooType = new TypeToken<Foo<Bar>>(){}.getType();
gson.toJson(foo, fooType);
gson.fromJson(json, fooType);
TypeToken 利用匿名內部類保留泛型簽名,getType() 返回 ParameterizedType。List<T>、Map<K,V>、自定義泛型類。Collection<Integer> ints = Arrays.asList(1,2,3,4,5);
String json = gson.toJson(ints); // "[1,2,3,4,5]"
Type type = new TypeToken<Collection<Integer>>(){}.getType();
Collection<Integer> ints2 = gson.fromJson(json, type);
JSON: ['hello', 5, {'name':'GREETINGS','source':'guest'}]
JsonParser / JsonReader)逐元素處理,類型安全、性能最優。Collection.class 映射到特定元素類型,副作用是影響其他集合反序列化。Collection<CommonType>。InstanceCreator。// InstanceCreator 示例
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 GsonBuilder().registerTypeAdapter(A.B.class, new InstanceCreatorForB(new A())).create();
當默認行為不符合預期(如 Joda-Time DateTime、自定義 ID 類),編寫 TypeAdapter。
class DateTimeSerializer implements JsonSerializer<DateTime> {
public JsonElement serialize(DateTime src, Type type, JsonSerializationContext ctx) {
return new JsonPrimitive(src.toString()); // 或自定義格式
}
}
class DateTimeDeserializer implements JsonDeserializer<DateTime> {
public DateTime deserialize(JsonElement json, Type type, JsonDeserializationContext ctx) {
return new DateTime(json.getAsJsonPrimitive().getAsString());
}
}
Gson gson = new GsonBuilder()
.registerTypeAdapter(DateTime.class, new DateTimeSerializer())
.registerTypeAdapter(DateTime.class, new DateTimeDeserializer())
.create();
Type 參數獲取實際類型參數(如 Id<T> 的 T)。class MoneyInstanceCreator implements InstanceCreator<Money> {
public Money createInstance(Type type) { return new Money("1000000", CurrencyCode.USD); }
}
Gson gson = new GsonBuilder().registerTypeAdapter(Money.class, new MoneyInstanceCreator()).create();
"",而非 null 或缺失。Gson gson = new GsonBuilder().serializeNulls().create();
// {"name":null,"age":20}
// 1. 工廠類
class NullStringToEmptyAdapterFactory implements TypeAdapterFactory {
public <T> TypeAdapter<T> create(Gson gson, TypeToken<T> type) {
if (type.getRawType() != String.class) return null;
return (TypeAdapter<T>) new StringNullAdapter();
}
}
// 2. 適配器
class StringNullAdapter extends TypeAdapter<String> {
public String read(JsonReader reader) throws IOException {
if (reader.peek() == JsonToken.NULL) { reader.nextNull(); return ""; }
return reader.nextString();
}
public void write(JsonWriter writer, String value) throws IOException {
if (value == null) { writer.nullValue(); return; }
writer.value(value);
}
}
// 3. 使用
Gson gson = new GsonBuilder()
.registerTypeAdapterFactory(new NullStringToEmptyAdapterFactory())
.create();
// 反序列化時 JSON null → Java ""
// 序列化時 Java null → JSON null (可再配合 serializeNulls())
class VersionedClass {
@Since(1.1) String newerField;
@Since(1.0) String newField;
String field;
}
Gson gson = new GsonBuilder().setVersion(1.0).create();
// 僅序列化版本 ≤ 1.0 的字段
excludeFieldsWithModifiers(Modifier.STATIC, Modifier.TRANSIENT)。excludeFieldsWithoutExposeAnnotation() + 字段標註 @Expose。shouldSkipClass/Field,支持任意邏輯(如按註解、類型、名稱模式過濾)。Gson gson = new GsonBuilder().setPrettyPrinting().create();
// 每行 80 字符,縮進 2 空格,左邊距 4 空格
序列化器/反序列化器需共享狀態時:
Gson 以「核心簡潔、擴展強大」著稱。掌握 TypeToken 泛型捕獲、TypeAdapter 自定義轉換、NullStringToEmptyAdapterFactory Null 安全、ExclusionStrategy 靈活過濾 四大進階技能,即可應對極其複雜的 JSON 交互場景。建議專案建立 GsonConfig 集中管理實例,並編寫單元測試覆蓋關鍵轉換邏輯。