Google Gson 是 Java 領域最輕量、最易用的 JSON 庫之一。其核心優勢在於:無需註解即可序列化實體類,同時通過註解提供靈活的字段控制。本文從基礎到進階,完整演示 List/Map 與 JSON 雙向轉換的最佳實踐。
toJson(Object):Java 對象 → JSON 字符串fromJson(String, Class/Type):JSON 字符串 → Java 對象GsonBuilder:構建定制化 Gson 實例(格式化、空值處理、註解策略等)public class Student {
private int id;
private String name;
private Date birthDay;
// Getter/Setter/toString 省略
}
Gson gson = new Gson();
Student s1 = new Student(); s1.setId(1); s1.setName("李坤"); s1.setBirthDay(new Date());
// 對象 → JSON
String json = gson.toJson(s1);
// 輸出: {"id":1,"name":"李坤","birthDay":"Jun 22, 2012 8:27:52 AM"}
// JSON → 對象
Student s2 = gson.fromJson(json, Student.class);
關鍵問題: Java 泛型擦除導致運行時無法直接獲取 List<Student> 類型,直接傳 List.class 會丟失泛型信息,反序列化出 List<LinkedTreeMap> 而非 List<Student>。
解決方案:TypeToken
List<Student> list = Arrays.asList(s1, s2, s3);
// List → JSON
String listJson = gson.toJson(list);
// 輸出: [{"id":1,"name":"李坤",...},{"id":2,"name":"曹貴生",...},{"id":3,"name":"柳波",...}]
// JSON → List<Student> 【關鍵:new TypeToken<List<Student>>(){}.getType()】
List<Student> retList = gson.fromJson(listJson, new TypeToken<List<Student>>(){}.getType());
for (Student stu : retList) { System.out.println(stu); }
TypeToken 利用匿名內部類保留泛型類型信息,getType() 返回實際的 ParameterizedType。Map<String, Student>、Set<Student> 等集合。Gson gson = new GsonBuilder()
.setPrettyPrinting() // 格式化輸出(縮進、換行)
.serializeNulls() // 序列化 null 字段(默認忽略)
.setDateFormat("yyyy-MM-dd HH:mm:ss") // 統一日期格式
.excludeFieldsWithoutExposeAnnotation() // 僅序列化 @Expose 字段
.create();
| 坑點 | 現象 | 解決 |
|---|---|---|
| 循環引用 | StackOverflowError | @Expose 控制字段、或編寫自定義 TypeAdapter 打破循環 |
| 日期格式不一致 | 前後端解析失敗 | 全局 setDateFormat 或字段級 @SerializedName + 自定義適配器 |
| 泛型擦除導致反序列化類型錯誤 | 得到 LinkedTreeMap | 必須使用 TypeToken 傳遞完整泛型類型 |
| 字段命名風格不匹配 | 駝峰 vs 下劃線 | setFieldNamingPolicy(FieldNamingPolicy.LOWER_CASE_WITH_UNDERSCORES) |
Map<String, Student> map = new HashMap<>();
map.put("s1", s1); map.put("s2", s2);
String mapJson = gson.toJson(map);
// {"s1":{"id":1,"name":"李坤",...},"s2":{"id":2,"name":"曹貴生",...}}
// 反序列化 Map
Type mapType = new TypeToken<Map<String, Student>>(){}.getType();
Map<String, Student> retMap = gson.fromJson(mapJson, mapType);
Gson 以「零配置啟動、按需深度定制」擊中 Java 開發者痛點。掌握 TypeToken 處理泛型、GsonBuilder 定制行為、@Expose/@SerializedName 字段級控制 三大核心技能,即可覆蓋 95% 以上的 JSON 交互場景。建議專案統一封裝 JsonUtils 工具類,集中管理 Gson 實例與異常處理。