系統整理 Gson 核心用法:基本物件轉換、JSON 陣列泛型捕獲、複雜巢狀結構解析、物件序列化為 JSON,含完整可執行測試代碼。
gson-2.x.jar 並加入 Build PathUser 類:屬性 name/age、無參建構子、getter/setter、toString()String jsonObj = "{\"name\":\"李四\",\"age\":30}";
String jsonArr = "[{\"name\":\"李四\",\"age\":40},{\"name\":\"張三\",\"age\":20},{\"name\":\"王五\",\"age\":30}]";
String jsonNest = "{\"status\":\"ok\",\"data\":[{\"name\":\"李四\",\"age\":30},{\"name\":\"張三\",\"age\":20},{\"name\":\"王五\",\"age\":30}]}";
private static void gsonTypeToken(String jsonArr) {
Gson gson = new Gson();
// TypeToken 匿名內部類捕獲泛型型別資訊(繞過類型擦除)
TypeToken<List<User>> token = new TypeToken<List<User>>() {};
List<User> users = gson.fromJson(jsonArr, token.getType());
for (User u : users) System.out.println(u);
}
原理:TypeToken 是 protected 抽象類,建立匿名子類時,JVM 保留泛型型別資訊,getType() 返回實際的 ParameterizedType。
// 對應 jsonNest 的資料類
class A {
private String status;
private List<User> data;
// getter/setter...
}
private static void gsonFinal(String jsonNest) {
Gson gson = new Gson();
A a = gson.fromJson(jsonNest, A.class);
if ("ok".equals(a.getStatus())) {
System.out.println(a.getStatus());
for (User u : a.getData()) System.out.println(u);
}
}
核心 API 總結
| 場景 | 方法 | 關鍵點 |
|---|---|---|
| 物件 → JSON | gson.toJson(obj) | 支援任意物件、陣列、集合、Map |
| JSON → 物件 | gson.fromJson(json, Class<T>) | 目標類需有無參建構子 |
| JSON 陣列 → List<T> | gson.fromJson(json, TypeToken<List<T>>{}.getType()) | 必須用 TypeToken 保留泛型 |
| 巢狀 JSON → 物件 | 定義 Wrapper 類映射層級 | 層級對應、集合屬性用 List<T> |
JsonIOException: Unable to invoke no-args constructorList.class 只能得到 List<LinkedTreeMap>@SerializedName("json_field") 映射new GsonBuilder().serializeNulls().create() 開啟yyyy-MM-dd'T'HH:mm:ss,可 GsonBuilder().setDateFormat("yyyy-MM-dd").create()Gson 設計哲學:約定優於配置。只要 POJO 結構與 JSON 結構對應,零配置自動完成雙向轉換。