首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> Java 程式設計 >> Java 相關知識

Gson 基礎入門教學:Java 對象與 JSON 互轉核心 API (toJson/fromJson) 與 TypeToken 泛型處理詳解

     編輯:Java 相關知識

前言:為什麼選擇 Gson?

Gson 是 Google 開源的 Java JSON 庫,以「零配置、支援泛型、無需註解、效能優異」著稱。本文面向初學者,從 Maven 引入、基本實體定義、toJson/fromJson 核心 API、單對象/列表/Map 轉換、TypeToken 處理泛型擦除、日期格式化、常見異常處理等全方位講解,附完整可運行代碼。


環境準備:Maven 依賴

<dependency> <groupId>com.google.code.gson</groupId> <artifactId>gson</artifactId> <version>2.10.1</version> </dependency>

實體類定義 (標準 Java Bean)

public class Person { private String name; private int age; private List<String> hobbies; private Address address; // getter/setter/toString 省略 // 內部類 Address public static class Address { private String city; private String street; // getter/setter } }

核心 API 雙雄:toJson / fromJson

1. 對象 → JSON 字符串

Gson gson = new Gson(); Person p = new Person(); p.setName("張三"); p.setAge(25); p.setHobbies(Arrays.asList("閱讀", "游泳")); p.setAddress(new Address("台北", "信義路")); String json = gson.toJson(p); System.out.println(json);

輸出

{"name":"張三","age":25,"hobbies":["閱讀","游泳"],"address":{"city":"台北","street":"信義路"}}

2. JSON 字符串 → 對象

String json = "{\"name\":\"李四\",\"age\":30,\"hobbies\":[\"跑步\"]}"; Person p2 = gson.fromJson(json, Person.class); System.out.println(p2.getName()); // 李四

進階場景:列表與 Map 轉換

List<Person> 序列化

List<Person> list = Arrays.asList(p, p2); String jsonList = gson.toJson(list); // [{"name":"張三",...},{"name":"李四",...}]

List<Person> 反序列化 (關鍵:TypeToken)

String jsonList = "[{\"name\":\"王五\",\"age\":20}]"; // ❌ 錯誤:gson.fromJson(jsonList, List.class) → List // ✅ 正確:TypeToken 捕獲泛型類型 List<Person> restored = gson.fromJson(jsonList, new TypeToken<List<Person>>() {}.getType());

Map<String, Person> 轉換

Map<String, Person> map = new LinkedHashMap<>(); map.put("user1", p); map.put("user2", p2); String jsonMap = gson.toJson(map); // {"user1":{...},"user2":{...}} // 反序列化 Map<String, Person> restoredMap = gson.fromJson(jsonMap, new TypeToken<Map<String, Person>>() {}.getType());

TypeToken 原理深度解析

為什麼需要 TypeToken?

Java 泛型在編譯期經過類型擦除,運行時 List<Person> 僅剩 List。Gson 無法從 List.class 知道元素類型,故反序列化為 List<LinkedTreeMap> (內部預設 Map 實現)。

TypeToken 如何解決?

// 匿名內部類繼承 TypeToken,利用繼承關係保留泛型簽名 TypeToken<List<Person>> token = new TypeToken<List<Person>>() {}; Type type = token.getType(); // 運行時可獲取完整 ParameterizedType

這是「超級類型令牌」模式,Gson 內部通過反射讀取匿名類的泛型父類簽名,還原完整類型資訊。


實用配置:GsonBuilder 客製化

Gson gson = new GsonBuilder() .setPrettyPrinting() // 格式化輸出 (縮排、換行) .serializeNulls() // 輸出 null 欄位 (預設忽略) .setDateFormat("yyyy-MM-dd HH:mm:ss") // 統一日期格式 .disableHtmlEscaping() // 不轉義 HTML 字符 (< > &) .enableComplexMapKeySerialization() // 支援非 String Key Map .create();

常見異常與解決方案

異常原因解決
JsonSyntaxException: Expected BEGIN_OBJECT but was BEGIN_ARRAYJSON 結構與目標類不匹配 (如傳陣列給單對象)檢查 JSON 結構、調整目標類型 (List/Map/陣列)
JsonParseException: Date format日期字符串不符合預設/配置格式統一 setDateFormat 或自訂 JsonDeserializer
StackOverflowError對象循環引用 (A→B→A)使用 @Expose 控制序列化欄位、或改用 Jackson @JsonIgnore
反序列化後 List 元素為 LinkedTreeMap未使用 TypeToken必須 new TypeToken<List<T>>(){}.getType()

完整可運行 Demo 類

public class GsonQuickStart { public static void main(String[] args) { Gson gson = new GsonBuilder().setPrettyPrinting().create(); // 1. 單對象 Person p = new Person("Alice", 28, Arrays.asList("Java", "Music")); String json = gson.toJson(p); System.out.println("=== toJson ==="); System.out.println(json); // 2. 反序列化 Person p2 = gson.fromJson(json, Person.class); System.out.println("=== fromJson ==="); System.out.println(p2); // 3. 列表 List<Person> list = Arrays.asList(p, p2); String listJson = gson.toJson(list); List<Person> restored = gson.fromJson(listJson, new TypeToken<List<Person>>(){}.getType()); System.out.println("=== List 恢復 ==="); restored.forEach(System.out::println); } }

總結與遷移建議

  • 入門首選:Gson API 簡潔、文檔豐富、社區活躍。
  • 效能優異:流式解析、字節碼生成優化,滿足多數業務場景。
  • 遷移 Jackson:若需更豐富註解 (@JsonIgnore, @JsonProperty)、多態序列化、模組化擴展,Jackson 是企業級標準選擇,遷移成本低 (API 相似)。
  • 最佳實踐:專案封裝 JsonUtils 統一 GsonBuilder 配置,業務代碼一行調用 JsonUtils.toJson(obj)/JsonUtils.fromJson(json, clazz)。

掌握 toJson/fromJson + TypeToken 這組核心組合,即可輕鬆應對 90% 的 JSON 處理需求。開始在你的專案中引入 Gson,享受「Java 對象自由穿梭 JSON 世界」的便利吧!

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved