Gson(JSON处理库)
# Gson(JSON处理库)
前言
Gson (也写作 google-gson) 是由 Google 开发并开源的一款功能强大、性能优异且易于使用的 Java 库,专门用于实现 Java 对象与 JSON (JavaScript Object Notation) 数据格式之间的相互转换(序列化与反序列化)。凭借其简洁的 API 设计、对复杂对象模型的良好支持以及无需强制注解的灵活性,Gson 在 Java 社区得到了广泛应用,尤其是在 Android 开发和众多后端服务(包括 Spring Boot 应用)中,是处理 JSON 数据的热门选择之一。本文将深入探讨 Gson 的核心功能、高级用法及实战技巧。
# 一、Gson 简介与环境配置
# 1.1 Gson 核心特性
Gson 之所以备受青睐,主要得益于以下几个核心优势:
- 易用性: 提供极其简单的
toJson()
和fromJson()
方法即可完成大部分转换任务。 - 无需注解: 对于标准 Java Bean,Gson 无需任何注解即可进行序列化和反序列化。当然,它也提供了
@SerializedName
、@Expose
等注解进行更细粒度的控制。 - 复杂对象支持: 能够自动处理任意复杂的 Java 对象,包括深层嵌套的对象、泛型集合等。
- 泛型支持: 通过
TypeToken
提供了对泛型类型的完美支持,解决了 Java 泛型擦除带来的问题。 - 自定义能力: 允许通过
GsonBuilder
定制序列化/反序列化的各种行为,如日期格式、字段命名策略、null 值处理、排除特定字段等,甚至可以注册自定义的TypeAdapter
实现完全控制。 - 性能良好: 在大多数场景下,Gson 提供了令人满意的性能表现。
- JSON 树模型: 提供了
JsonElement
、JsonObject
、JsonArray
等类,允许以类似 DOM 的方式操作 JSON 结构,适合处理动态或未知结构的 JSON 数据。
# 1.2 添加 Gson 依赖
要在项目中使用 Gson,首先需要将其库文件添加到项目的依赖中。
Maven 项目依赖配置:
在你的 pom.xml
文件中,添加以下 <dependency>
:
<dependency>
<groupId>com.google.code.gson</groupId>
<artifactId>gson</artifactId>
<!-- 建议查阅 Gson 官方仓库获取最新的稳定版本 -->
<version>2.9.0</version>
</dependency>
2
3
4
5
6
注意:
2.9.0
是编写本文时的一个常用稳定版本。请访问 Gson 的 Maven Central (opens new window) 或 GitHub Releases (opens new window) 页面查找并使用最新的推荐版本(例如 2.10.1 或更高)。
Gradle 项目依赖配置:
在你的 build.gradle
(或 build.gradle.kts
) 文件中,添加以下依赖:
// build.gradle (Groovy DSL)
implementation 'com.google.code.gson:gson:2.9.0' // 同样,请使用最新稳定版本
// build.gradle.kts (Kotlin DSL)
// implementation("com.google.code.gson:gson:2.9.0")
2
3
4
5
# 二、基础操作:Java 对象与 JSON 的互转
Gson 的核心功能在于 Java 对象和 JSON 字符串之间的双向转换。
# 2.1 Java 对象序列化为 JSON 字符串
序列化是将 Java 对象的状态转换为 JSON 字符串的过程。
import com.google.gson.Gson;
/**
* Gson 示例:将 Java 对象序列化为 JSON 字符串
*/
public class GsonObjectToJsonExample {
public static void main(String[] args) {
// 1. 创建 Gson 实例
// Gson 实例是线程安全的,可以重用
Gson gson = new Gson();
// 2. 创建一个需要被序列化的 Java 对象 (POJO)
User user = new User("张三", 25);
// 3. 调用 toJson() 方法将 Java 对象转换为 JSON 字符串
String jsonString = gson.toJson(user);
// 4. 输出生成的 JSON 字符串
System.out.println("Java 对象序列化为 JSON 字符串: " + jsonString);
// 预期输出: {"name":"张三","age":25}
}
}
/**
* 用户 POJO 类 (Plain Old Java Object)
* Gson 默认会序列化所有非 transient、非 static 的字段
*/
class User {
private String name; // 用户姓名
private int age; // 用户年龄
// private transient String password; // 使用 transient 关键字可以阻止 Gson 序列化该字段
// Gson 反序列化通常需要一个无参构造函数 (可以是 private)
// 如果没有无参构造函数,Gson 会尝试使用 Unsafe 创建实例 (可能不稳定)
// public User() {}
// 用于创建对象的构造函数
public User(String name, int age) {
this.name = name;
this.age = age;
}
// Gson 序列化/反序列化不强制要求 Getter/Setter 方法,
// 它默认可以通过反射直接访问字段 (即使是 private)。
// 但提供 Getter/Setter 是良好的面向对象实践。
public String getName() { return name; }
public void setName(String name) { this.name = name; }
public int getAge() { return age; }
public void setAge(int age) { this.age = age; }
@Override
public String toString() {
return "User{" + "name='" + name + '\'' + ", age=" + age + '}';
}
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
# 2.2 JSON 字符串反序列化为 Java 对象
反序列化是将 JSON 字符串解析并填充到 Java 对象中的过程。
import com.google.gson.Gson;
import com.google.gson.JsonSyntaxException; // 用于捕获 JSON 格式错误
/**
* Gson 示例:将 JSON 字符串反序列化为 Java 对象
*/
public class GsonJsonToObjectExample {
public static void main(String[] args) {
// 1. 创建 Gson 实例
Gson gson = new Gson();
// 2. 准备一个待解析的 JSON 字符串
String jsonString = "{\"name\":\"李四\",\"age\":30, \"email\":\"lisi@example.com\"}"; // 包含 email 字段
try {
// 3. 调用 fromJson() 方法将 JSON 字符串转换为指定类型的 Java 对象
// 第一个参数是 JSON 字符串或 Reader
// 第二个参数是目标 Java 类的 Class 对象
User user = gson.fromJson(jsonString, User.class);
// 4. 输出反序列化后 Java 对象的信息
// 注意:即使 JSON 中有 email 字段,但 User 类没有对应字段,Gson 默认会忽略它
System.out.println("JSON 字符串成功反序列化为 User 对象:");
System.out.println("- 姓名: " + user.getName());
System.out.println("- 年龄: " + user.getAge());
// 预期输出:
// JSON 字符串成功反序列化为 User 对象:
// - 姓名: 李四
// - 年龄: 30
} catch (JsonSyntaxException e) {
// 处理可能发生的 JSON 格式错误
System.err.println("JSON 解析错误: " + e.getMessage());
}
// 示例:处理格式错误的 JSON
String invalidJson = "{\"name\":\"王五\", age:invalid}"; // age 值格式错误
try {
gson.fromJson(invalidJson, User.class);
} catch (JsonSyntaxException e) {
System.err.println("解析无效 JSON 时捕获到异常: " + e.getMessage());
}
}
// User 类定义同上一个示例
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
核心 API:
Gson()
: 创建一个具有默认配置的Gson
实例。GsonBuilder()
: 用于创建具有自定义配置的Gson
实例(将在后续章节介绍)。toJson(Object src)
: 将指定的 Java 对象序列化为其 JSON 表示形式(字符串)。fromJson(String json, Class<T> classOfT)
: 将指定的 JSON 字符串反序列化为指定Class
类型的对象。fromJson(Reader json, Class<T> classOfT)
: 从Reader
读取并反序列化。fromJson(String json, Type typeOfT)
: 用于反序列化为泛型类型(如List<User>
),将在集合处理部分介绍。
# 三、高级应用:复杂 JSON 数据处理
当 JSON 结构复杂、嵌套层次深,或结构不固定时,可以使用 Gson 提供的树模型 (JsonElement
, JsonObject
, JsonArray
) 进行更灵活的操作。
# 3.1 嵌套 JSON 结构解析 (使用 JsonObject)
JsonObject
允许像操作 Map
一样访问 JSON 对象的属性。
import com.google.gson.Gson;
import com.google.gson.JsonObject;
import com.google.gson.JsonElement; // 引入 JsonElement
import com.google.gson.JsonSyntaxException;
/**
* Gson 示例:使用 JsonObject 解析嵌套 JSON 结构
*/
public class GsonNestedJsonExample {
public static void main(String[] args) {
// 1. 创建 Gson 实例
Gson gson = new Gson();
// 2. 准备一个包含嵌套对象的 JSON 字符串
String jsonString = "{"
+ "\"name\": \"赵六\","
+ "\"age\": 22,"
+ "\"active\": true,"
+ "\"address\": {" // address 是一个嵌套的 JSON 对象
+ "\"city\": \"上海\","
+ "\"district\": \"浦东新区\","
+ "\"zip\": \"200120\""
+ "},"
+ "\"scores\": [95, 88, 76]" // 包含一个 JSON 数组
+ "}";
try {
// 3. 将 JSON 字符串解析为 JsonObject
// 使用 fromJson() 并指定目标类型为 JsonObject.class
JsonObject jsonObject = gson.fromJson(jsonString, JsonObject.class);
// 4. 访问顶层基本类型的属性
// 使用 get() 方法获取 JsonElement,然后使用 asString, asInt, asBoolean 等获取具体类型的值
String name = jsonObject.get("name").getAsString();
int age = jsonObject.get("age").getAsInt();
boolean active = jsonObject.get("active").getAsBoolean();
System.out.println("基本信息:");
System.out.println("- 姓名: " + name);
System.out.println("- 年龄: " + age);
System.out.println("- 是否活跃: " + active);
// 5. 访问嵌套的 JSON 对象 (address)
// 使用 get() 获取代表 address 的 JsonElement,然后使用 getAsJsonObject() 转换为 JsonObject
JsonObject addressObject = jsonObject.getAsJsonObject("address"); // 更简洁的写法
// 或者: JsonObject addressObject = jsonObject.get("address").getAsJsonObject();
if (addressObject != null) { // 推荐检查是否为 null
String city = addressObject.get("city").getAsString();
String district = addressObject.get("district").getAsString();
String zip = addressObject.get("zip").getAsString();
System.out.println("地址信息:");
System.out.println("- 城市: " + city);
System.out.println("- 区县: " + district);
System.out.println("- 邮编: " + zip);
}
// 6. 检查属性是否存在 (推荐使用 has() 方法)
if (jsonObject.has("email")) {
System.out.println("- 邮箱: " + jsonObject.get("email").getAsString());
} else {
System.out.println("- 邮箱: 未提供");
}
// 7. 安全地获取属性 (处理 null 或不存在的情况)
// 先检查是否存在,或获取 JsonElement 后检查是否为 JsonNull
JsonElement ageElement = jsonObject.get("age");
if (ageElement != null && !ageElement.isJsonNull()) {
// 处理 age...
}
// Gson 的 getAsXXX 通常在 null 或类型不匹配时抛异常,不如先判断或使用 POJO 映射安全
} catch (JsonSyntaxException e) {
System.err.println("JSON 解析错误: " + e.getMessage());
} catch (NullPointerException | IllegalStateException e) {
// 处理获取属性或类型转换时可能发生的错误
System.err.println("访问 JSON 属性时出错: " + e.getMessage());
}
}
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
输出结果:
基本信息:
- 姓名: 赵六
- 年龄: 22
- 是否活跃: true
地址信息:
- 城市: 上海
- 区县: 浦东新区
- 邮编: 200120
- 邮箱: 未提供
2
3
4
5
6
7
8
9
# 3.2 JSON 数组处理 (使用 JsonArray)
JsonArray
允许像操作 List
一样遍历和访问 JSON 数组的元素。
import com.google.gson.Gson;
import com.google.gson.JsonArray;
import com.google.gson.JsonObject; // 需要引入 JsonObject
import com.google.gson.JsonElement; // 需要引入 JsonElement
import com.google.gson.JsonSyntaxException;
/**
* Gson 示例:使用 JsonArray 处理 JSON 数组
*/
public class GsonArrayExample {
public static void main(String[] args) {
// 1. 创建 Gson 实例
Gson gson = new Gson();
// 2. 准备一个 JSON 数组字符串,包含多个用户对象
String jsonString = "["
+ "{\"name\":\"张三\",\"age\":25,\"city\":\"北京\"},"
+ "{\"name\":\"李四\",\"age\":30,\"city\":\"上海\"},"
+ "{\"name\":\"王五\",\"age\":28,\"city\":\"广州\"}"
+ "]";
try {
// 3. 将 JSON 字符串解析为 JsonArray
JsonArray jsonArray = gson.fromJson(jsonString, JsonArray.class);
// 或者使用 JsonParser (更通用,自动识别根是对象还是数组)
// JsonArray jsonArray = JsonParser.parseString(jsonString).getAsJsonArray();
System.out.println("JSON 数组包含 " + jsonArray.size() + " 个元素。");
// 4. 遍历 JsonArray
System.out.println("\n遍历 JSON 数组:");
// 方法一:使用增强 for-each 循环 (元素类型是 JsonElement)
for (JsonElement element : jsonArray) {
// 需要将 JsonElement 转换为 JsonObject 来访问其属性
if (element.isJsonObject()) { // 检查元素是否为 JSON 对象
JsonObject userObject = element.getAsJsonObject();
String name = userObject.get("name").getAsString();
int age = userObject.get("age").getAsInt();
String city = userObject.get("city").getAsString();
System.out.println(" - 姓名: " + name + ", 年龄: " + age + ", 城市: " + city);
}
}
// 方法二:使用索引访问 (类似 List)
if (jsonArray.size() > 1) {
JsonObject secondUser = jsonArray.get(1).getAsJsonObject(); // 获取第二个元素
System.out.println("\n访问第二个用户:");
System.out.println(" - 姓名: " + secondUser.get("name").getAsString());
}
// 方法三:使用 Java 8 Stream API
System.out.println("\n使用 Stream API 过滤和输出:");
jsonArray.asList().stream() // JsonArray 可以通过 asList() 转为 List<JsonElement>
.map(JsonElement::getAsJsonObject) // 转换为 JsonObject 流
.filter(obj -> obj.get("age").getAsInt() > 28) // 过滤年龄大于 28 的用户
.forEach(user -> System.out.println(" - 年龄大于 28 的用户: " + user.get("name").getAsString()));
} catch (JsonSyntaxException e) {
System.err.println("JSON 解析错误: " + e.getMessage());
} catch (IllegalStateException e) {
System.err.println("访问 JSON 元素时出错(例如,尝试将非对象元素作为对象访问): " + e.getMessage());
}
}
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
输出结果:
JSON 数组包含 3 个元素。
遍历 JSON 数组:
- 姓名: 张三, 年龄: 25, 城市: 北京
- 姓名: 李四, 年龄: 30, 城市: 上海
- 姓名: 王五, 年龄: 28, 城市: 广州
访问第二个用户:
- 姓名: 李四
使用 Stream API 过滤和输出:
- 年龄大于 28 的用户: 李四
2
3
4
5
6
7
8
9
10
11
12
树模型 API 核心:
JsonParser.parseString(String json)
: (推荐) 静态方法,将 JSON 字符串解析为JsonElement
(可能是JsonObject
,JsonArray
,JsonPrimitive
,JsonNull
)。gson.fromJson(String json, Class<T> classOfT)
: 也可以用来解析为JsonObject.class
或JsonArray.class
。JsonElement
: JSON 树模型的基类。isJsonObject()
,getAsJsonObject()
: 判断并转换为JsonObject
。
isJsonArray()
,getAsJsonArray()
: 判断并转换为JsonArray
。isJsonPrimitive()
,getAsJsonPrimitive()
: 判断并转换为JsonPrimitive
(表示字符串、数字、布尔值)。isJsonNull()
: 判断是否为 JSONnull
。
JsonObject
:get(String memberName)
: 获取指定名称的JsonElement
。has(String memberName)
: 检查是否存在指定名称的成员。getAsJsonObject(String memberName)
,getAsJsonArray(String memberName)
: 获取并直接转换为JsonObject
或JsonArray
。add(String property, JsonElement value)
: 添加或替换属性。remove(String property)
: 移除属性。
JsonArray
:get(int index)
: 获取指定索引的JsonElement
。size()
: 获取数组大小。add(JsonElement element)
: 添加元素。remove(int index)
: 移除元素。asList()
: 将JsonArray
转换为List<JsonElement>
(Java 8 Stream API 友好)。
JsonPrimitive
:getAsString()
,getAsInt()
,getAsDouble()
,getAsBoolean()
,getAsBigDecimal()
,getAsBigInteger()
,getAsNumber()
: 获取原始值。
使用树模型可以非常灵活地处理结构未知或动态变化的 JSON,但代码通常比直接映射 POJO 更繁琐。
# 四、集合类型处理:JSON 与 Java 集合互转
Gson 对 Java 的集合类型(如 List
, Map
)提供了良好的支持,尤其擅长处理泛型集合。
# 4.1 JSON 数组字符串转换为 List 集合
处理 JSON 数组到 Java List
的转换,特别是当 List
包含泛型对象(如 List<User>
)时,需要使用 TypeToken
来解决 Java 泛型擦除的问题。
import com.google.gson.Gson;
import com.google.gson.reflect.TypeToken; // 引入 TypeToken
import com.google.gson.JsonSyntaxException;
import java.lang.reflect.Type; // 引入 Type
import java.util.List;
import java.util.ArrayList; // 可以是 ArrayList 或其他 List 实现
/**
* Gson 示例:将 JSON 数组字符串反序列化为 Java List 集合
*/
public class GsonJsonToListExample {
public static void main(String[] args) {
// 1. 创建 Gson 实例
Gson gson = new Gson();
// 2. 准备一个包含多个用户对象的 JSON 数组字符串
String jsonString = "["
+ "{\"name\":\"张三\",\"age\":25},"
+ "{\"name\":\"李四\",\"age\":30},"
+ "{\"name\":\"王五\",\"age\":28}"
+ "]";
try {
// 3. 创建目标泛型类型的 Type 对象
// 使用 TypeToken 的匿名子类来捕获完整的泛型类型信息 (List<User>)
Type userListType = new TypeToken<ArrayList<User>>() {}.getType();
// 注意:这里使用 ArrayList<User> 或 List<User> 都可以,
// Gson 会根据 JSON 结构创建合适的 List 实现 (通常是 ArrayList)。
// 4. 调用 fromJson() 方法,传入 JSON 字符串和 Type 对象
List<User> userList = gson.fromJson(jsonString, userListType);
// 5. 遍历并输出反序列化后的 List<User> 集合
System.out.println("JSON 数组成功反序列化为 List<User>:");
if (userList != null) {
userList.forEach(user ->
System.out.println(" - 姓名: " + user.getName() + ", 年龄: " + user.getAge())
);
}
// 预期输出:
// 姓名: 张三, 年龄: 25
// 姓名: 李四, 年龄: 30
// 姓名: 王五, 年龄: 28
// 示例:反序列化基本类型的 List
String numbersJson = "[10, 20, 30, 40, 50]";
Type integerListType = new TypeToken<List<Integer>>() {}.getType();
List<Integer> numbers = gson.fromJson(numbersJson, integerListType);
System.out.println("\nJSON 数组反序列化为 List<Integer>:");
System.out.println(" " + numbers); // 输出: [10, 20, 30, 40, 50]
} catch (JsonSyntaxException e) {
System.err.println("JSON 解析错误: " + e.getMessage());
}
}
// User 类定义同上
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
关键点: TypeToken
通过创建一个带有泛型参数的匿名子类,利用 Java 的类型系统在运行时保留了完整的泛型信息(如 List<User>
),从而让 Gson 知道应该将 JSON 数组中的每个对象反序列化为什么类型。
# 4.2 JSON 对象字符串转换为 Map 集合
将 JSON 对象转换为 Java Map
同样需要使用 TypeToken
来指定键和值的泛型类型。
import com.google.gson.Gson;
import com.google.gson.reflect.TypeToken;
import com.google.gson.JsonSyntaxException;
import java.lang.reflect.Type;
import java.util.Map;
/**
* Gson 示例:将 JSON 对象字符串反序列化为 Java Map 集合
*/
public class GsonJsonToMapExample {
public static void main(String[] args) {
// 1. 创建 Gson 实例
Gson gson = new Gson();
// 2. 准备一个 JSON 对象字符串
String jsonString = "{"
+ "\"name\": \"张三\", "
+ "\"age\": 25, "
+ "\"city\": \"北京\", "
+ "\"isVip\": true, "
+ "\"balance\": 100.50 "
+ "}";
try {
// 3. 创建目标泛型类型的 Type 对象 (Map<String, Object>)
// String 是键的类型,Object 是值的类型 (因为值可以是不同类型)
Type mapType = new TypeToken<Map<String, Object>>() {}.getType();
// 4. 调用 fromJson() 方法将 JSON 字符串转换为 Map
Map<String, Object> userMap = gson.fromJson(jsonString, mapType);
// 5. 访问 Map 中的数据
System.out.println("JSON 对象成功反序列化为 Map<String, Object>:");
System.out.println("- 姓名 (String): " + userMap.get("name"));
// 注意:Gson 默认会将 JSON 数字解析为 Double 类型
System.out.println("- 年龄 (Double): " + userMap.get("age"));
// 需要手动转换为 Integer 或其他数字类型
int age = ((Double) userMap.get("age")).intValue();
System.out.println("- 年龄 (int): " + age);
System.out.println("- 城市 (String): " + userMap.get("city"));
System.out.println("- 是否 VIP (Boolean): " + userMap.get("isVip"));
System.out.println("- 余额 (Double): " + userMap.get("balance"));
// 遍历 Map
System.out.println("\n遍历 Map:");
userMap.forEach((key, value) ->
System.out.println(" - Key: " + key + ", Value: " + value + " (Type: " + value.getClass().getSimpleName() + ")")
);
} catch (JsonSyntaxException e) {
System.err.println("JSON 解析错误: " + e.getMessage());
} catch (ClassCastException e) {
System.err.println("类型转换错误: " + e.getMessage());
}
}
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
输出结果:
JSON 对象成功反序列化为 Map<String, Object>:
- 姓名 (String): 张三
- 年龄 (Double): 25.0
- 年龄 (int): 25
- 城市 (String): 北京
- 是否 VIP (Boolean): true
- 余额 (Double): 100.5
遍历 Map:
- Key: name, Value: 张三 (Type: String)
- Key: age, Value: 25.0 (Type: Double)
- Key: city, Value: 北京 (Type: String)
- Key: isVip, Value: true (Type: Boolean)
- Key: balance, Value: 100.5 (Type: Double)
2
3
4
5
6
7
8
9
10
11
12
13
14
注意: Gson 在将 JSON 数字反序列化到 Map<String, Object>
的 Object
值时,默认会使用 Double
类型。如果需要特定的数字类型(如 Integer
, Long
, BigDecimal
),需要在使用时进行类型转换,或者考虑使用 JsonObject
树模型进行更精确的类型处理。
# 4.3 Java 集合序列化为 JSON 字符串
将 Java List
或 Map
序列化为 JSON 字符串非常直接,使用 gson.toJson()
即可。
import com.google.gson.Gson;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
/**
* Gson 示例:将 Java List 和 Map 集合序列化为 JSON 字符串
*/
public class GsonCollectionToJsonExample {
public static void main(String[] args) {
// 1. 创建 Gson 实例
Gson gson = new Gson();
// --- List 转 JSON 数组字符串 ---
// 创建一个用户 List
List<User> userList = new ArrayList<>();
userList.add(new User("张三", 25));
userList.add(new User("李四", 30));
userList.add(new User("王五", 28));
// 调用 toJson() 将 List 转换为 JSON 数组字符串
String listJsonString = gson.toJson(userList);
System.out.println("List<User> 序列化为 JSON 数组字符串:");
System.out.println(listJsonString);
// 预期输出: [{"name":"张三","age":25},{"name":"李四","age":30},{"name":"王五","age":28}]
// --- Map 转 JSON 对象字符串 ---
// 创建一个 Map 对象
Map<String, Object> dataMap = new HashMap<>();
dataMap.put("appName", "My Application");
dataMap.put("version", "1.2.0");
dataMap.put("enabled", true);
dataMap.put("retryCount", 3);
// 嵌套 Map
Map<String, String> theme = new HashMap<>();
theme.put("color", "blue");
theme.put("font", "Arial");
dataMap.put("themeConfig", theme);
// 调用 toJson() 将 Map 转换为 JSON 对象字符串
String mapJsonString = gson.toJson(dataMap);
System.out.println("\nMap<String, Object> 序列化为 JSON 对象字符串:");
System.out.println(mapJsonString);
// 预期输出: {"appName":"My Application","version":"1.2.0","enabled":true,"retryCount":3,"themeConfig":{"color":"blue","font":"Arial"}}
// 注意:HashMap 不保证顺序,输出的字段顺序可能不同
}
// User 类定义同上
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
# 五、自定义序列化与反序列化
Gson 提供了强大的自定义能力,允许开发者控制 JSON 转换的细节。
# 5.1 自定义日期格式 (GsonBuilder
)
默认情况下,Gson 对 java.util.Date
的序列化格式可能不是我们期望的。可以使用 GsonBuilder
来指定日期格式。
import com.google.gson.Gson;
import com.google.gson.GsonBuilder; // 引入 GsonBuilder
import java.util.Date;
/**
* Gson 示例:使用 GsonBuilder 自定义日期格式
*/
public class GsonDateFormatExample {
public static void main(String[] args) {
// 1. 创建 GsonBuilder 实例
GsonBuilder gsonBuilder = new GsonBuilder();
// 2. 使用 setDateFormat() 指定日期格式模式
// 可以是 SimpleDateFormat 支持的任何有效模式
String dateFormatPattern = "yyyy-MM-dd HH:mm:ssXXX"; // ISO 8601 格式,带时区
gsonBuilder.setDateFormat(dateFormatPattern);
// 3. (可选) 配置其他选项,如格式化输出
// gsonBuilder.setPrettyPrinting();
// 4. 调用 create() 方法创建配置好的 Gson 实例
Gson gson = gsonBuilder.create();
// 5. 创建包含 Date 字段的对象
Event event = new Event("系统发布", new Date());
// 6. 使用配置好的 Gson 实例进行序列化
String jsonString = gson.toJson(event);
System.out.println("使用自定义日期格式序列化的 JSON:");
System.out.println(jsonString);
// 预期输出类似: {"eventName":"系统发布","eventTime":"2024-08-20 17:30:00+08:00"} (具体时间会变化)
// 7. 使用配置好的 Gson 实例进行反序列化
// JSON 字符串中的日期格式必须与 Gson 配置的格式匹配
String inputJson = "{\"eventName\":\"维护窗口\",\"eventTime\":\"2023-10-01 02:00:00+00:00\"}";
try {
Event parsedEvent = gson.fromJson(inputJson, Event.class);
System.out.println("\n反序列化得到的 Date 对象:");
// 输出 Date 对象(其 toString() 格式可能与序列化格式不同)
System.out.println(parsedEvent.getEventTime());
} catch (Exception e) {
System.err.println("反序列化日期时出错: " + e.getMessage());
}
}
}
/**
* 包含 Date 字段的事件类
*/
class Event {
private String eventName;
private Date eventTime;
public Event(String eventName, Date eventTime) {
this.eventName = eventName;
this.eventTime = eventTime;
}
// Getters and Setters...
public String getEventName() { return eventName; }
public void setEventName(String eventName) { this.eventName = eventName; }
public Date getEventTime() { return eventTime; }
public void setEventTime(Date eventTime) { this.eventTime = eventTime; }
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
# 5.2 忽略特定字段
有多种方法可以在 Gson 序列化/反序列化时忽略 Java 对象的某些字段:
- 使用
transient
关键字: 这是 Java 原生的方式,被transient
修饰的字段默认不会被 Gson 序列化。 - 使用
@Expose
注解: 结合GsonBuilder.excludeFieldsWithoutExposeAnnotation()
,可以实现白名单机制,只序列化/反序列化明确标记了@Expose
的字段。 - 使用
ExclusionStrategy
: (更高级) 通过GsonBuilder.setExclusionStrategies()
添加自定义排除策略,可以根据字段名、类型、注解等复杂条件来决定是否排除。
示例:使用 @Expose
注解
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import com.google.gson.annotations.Expose; // 引入 Expose 注解
/**
* Gson 示例:使用 @Expose 注解控制字段的序列化和反序列化
*/
public class GsonExposeExample {
public static void main(String[] args) {
// 1. 创建 GsonBuilder 并启用 @Expose 支持
Gson gson = new GsonBuilder()
// 调用此方法后,只有显式标记了 @Expose 的字段才会被处理
.excludeFieldsWithoutExposeAnnotation()
// (可选) 启用格式化输出
.setPrettyPrinting()
.create();
// 2. 创建带有 @Expose 注解的对象实例
UserProfile user = new UserProfile("张三", 25, "zhangsan@example.com", "内部备注", "123456");
// 3. 序列化对象
// 只有 name, age, email 字段 (标记了 @Expose) 会被包含
String jsonString = gson.toJson(user);
System.out.println("--- 使用 @Expose 序列化后的 JSON ---");
System.out.println(jsonString);
// 预期输出:
// {
// "name": "张三",
// "age": 25,
// "email": "zhangsan@example.com"
// }
// 4. 准备用于反序列化的 JSON (包含所有字段)
String inputJson = "{"
+ "\"name\": \"李四\", "
+ "\"age\": 30, "
+ "\"email\": \"lisi@example.com\", "
+ "\"internalNotes\": \"这是李四的备注\", " // 此字段在类中无 @Expose
+ "\"password\": \"secret\"" // 此字段在类中无 @Expose
+ "}";
// 5. 反序列化 JSON
UserProfile parsedUser = gson.fromJson(inputJson, UserProfile.class);
// 输出反序列化后的对象状态
// 只有 name, age, email 被成功赋值,internalNotes 和 password 保持默认值 (null)
System.out.println("\n--- 使用 @Expose 反序列化后的 UserProfile 对象 ---");
System.out.println("Name: " + parsedUser.getName());
System.out.println("Age: " + parsedUser.getAge());
System.out.println("Email: " + parsedUser.getEmail());
System.out.println("Internal Notes: " + parsedUser.getInternalNotes()); // 应为 null
System.out.println("Password: " + parsedUser.getPassword()); // 应为 null
}
}
/**
* 使用 @Expose 注解控制字段可见性的用户资料类
*/
class UserProfile {
// @Expose 默认同时对序列化和反序列化生效
@Expose
private String name;
@Expose
private int age;
@Expose(serialize = true, deserialize = true) // 显式指定序列化和反序列化都包含 (默认行为)
private String email;
// 没有 @Expose 注解,当 excludeFieldsWithoutExposeAnnotation() 启用时,此字段会被忽略
private String internalNotes;
// 也可以将 @Expose 用在 transient 字段上,如果需要强制包含它
// @Expose transient String temporaryData;
// 假设密码也不希望被序列化/反序列化
private transient String password; // 使用 transient 也可以忽略
public UserProfile(String name, int age, String email, String internalNotes, String password) {
this.name = name;
this.age = age;
this.email = email;
this.internalNotes = internalNotes;
this.password = password;
}
// Getters and Setters...
public String getName() { return name; }
public void setName(String name) { this.name = name; }
public int getAge() { return age; }
public void setAge(int age) { this.age = age; }
public String getEmail() { return email; }
public void setEmail(String email) { this.email = email; }
public String getInternalNotes() { return internalNotes; }
public void setInternalNotes(String internalNotes) { this.internalNotes = internalNotes; }
public String getPassword() { return password; }
public void setPassword(String password) { this.password = password; }
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
# 5.3 指定 JSON 字段名 (@SerializedName
)
如果 Java 字段名与 JSON 字段名不一致(例如 Java 驼峰 vs JSON 下划线),可以使用 @SerializedName
注解。
import com.google.gson.Gson;
import com.google.gson.annotations.SerializedName; // 引入 SerializedName 注解
/**
* Gson 示例:使用 @SerializedName 指定 JSON 字段名
*/
public class GsonSerializedNameExample {
public static void main(String[] args) {
Gson gson = new Gson();
// --- 序列化 ---
Product product = new Product("P001", "智能手表", 1999.99, 50);
String jsonOutput = gson.toJson(product);
System.out.println("--- 使用 @SerializedName 序列化 ---");
System.out.println(jsonOutput);
// 预期输出: {"product_id":"P001","productName":"智能手表","unit_price":1999.99,"stock_count":50}
// --- 反序列化 ---
String jsonInput = "{\"product_id\":\"P002\",\"productName\":\"无线充电器\",\"unit_price\":199.0,\"stock_count\":100}";
Product parsedProduct = gson.fromJson(jsonInput, Product.class);
System.out.println("\n--- 使用 @SerializedName 反序列化 ---");
System.out.println("产品 ID: " + parsedProduct.getProductId());
System.out.println("产品名称: " + parsedProduct.getProductName());
System.out.println("单价: " + parsedProduct.getUnitPrice());
System.out.println("库存: " + parsedProduct.getStockCount());
}
}
/**
* 使用 @SerializedName 映射 JSON 字段名的产品类
*/
class Product {
// 将 Java 字段 productId 映射到 JSON 字段 product_id
@SerializedName("product_id")
private String productId;
// 字段名相同,可以不加注解,但加上也无妨
@SerializedName("productName")
private String productName;
// 将 Java 字段 unitPrice 映射到 JSON 字段 unit_price
@SerializedName("unit_price")
private double unitPrice;
// @SerializedName 也可以提供备选名称 (反序列化时用)
@SerializedName(value = "stock_count", alternate = {"stock", "count"})
private int stockCount;
public Product(String productId, String productName, double unitPrice, int stockCount) {
this.productId = productId;
this.productName = productName;
this.unitPrice = unitPrice;
this.stockCount = stockCount;
}
// Getters and Setters...
public String getProductId() { return productId; }
public void setProductId(String productId) { this.productId = productId; }
public String getProductName() { return productName; }
public void setProductName(String productName) { this.productName = productName; }
public double getUnitPrice() { return unitPrice; }
public void setUnitPrice(double unitPrice) { this.unitPrice = unitPrice; }
public int getStockCount() { return stockCount; }
public void setStockCount(int stockCount) { this.stockCount = stockCount; }
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
# 六、Gson 高级配置选项 (GsonBuilder
)
GsonBuilder
是配置和创建自定义 Gson
实例的工厂类,提供了丰富的选项。
# 6.1 格式化 JSON 输出 (setPrettyPrinting
)
使输出的 JSON 字符串带有缩进和换行,提高可读性。
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
// 引入之前的 UserWithAddress 和 Address 类定义
/**
* Gson 示例:使用 setPrettyPrinting 格式化 JSON 输出
*/
public class GsonPrettyPrintingExample {
public static void main(String[] args) {
// 1. 创建 GsonBuilder 并启用格式化输出
Gson gson = new GsonBuilder()
.setPrettyPrinting() // 启用"漂亮打印"
.create();
// 2. 创建一个嵌套结构的对象
Address address = new Address("北京", "朝阳区", "100020");
UserWithAddress user = new UserWithAddress("张三", 25, address);
// 3. 序列化为格式化的 JSON 字符串
String prettyJson = gson.toJson(user);
System.out.println("--- 格式化后的 JSON 输出 ---");
System.out.println(prettyJson);
/* 预期输出:
{
"name": "张三",
"age": 25,
"address": {
"city": "北京",
"district": "朝阳区",
"zipCode": "100020"
}
}
*/
}
}
// 需要包含之前定义的 Address 和 UserWithAddress 类
class Address {
private String city; // 城市
private String district; // 区县
private String zipCode; // 邮编
public Address(String city, String district, String zipCode) { this.city = city; this.district = district; this.zipCode = zipCode; }
// Getters...
}
class UserWithAddress {
private String name; // 用户姓名
private int age; // 用户年龄
private Address address; // 用户地址
public UserWithAddress(String name, int age, Address address) { this.name = name; this.age = age; this.address = address; }
// Getters...
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
# 6.2 处理 null 值 (serializeNulls
)
默认情况下,Gson 在序列化时会忽略值为 null
的字段。可以使用 serializeNulls()
让 Gson 输出这些 null
值。
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
// 引入之前的 User 类定义
/**
* Gson 示例:使用 serializeNulls 控制 null 值的序列化
*/
public class GsonNullValueExample {
public static void main(String[] args) {
// --- 默认行为:忽略 null ---
Gson defaultGson = new Gson();
User userWithNull = new User("张三", 25);
userWithNull.setName(null); // 将 name 设置为 null
String defaultJson = defaultGson.toJson(userWithNull);
System.out.println("--- 默认序列化 (忽略 null) ---");
System.out.println(defaultJson); // 预期输出: {"age":25}
// --- 配置为序列化 null ---
Gson gsonWithNulls = new GsonBuilder()
.serializeNulls() // 调用此方法以包含 null 值
.create();
String jsonWithNulls = gsonWithNulls.toJson(userWithNull);
System.out.println("\n--- 使用 serializeNulls() 序列化 ---");
System.out.println(jsonWithNulls); // 预期输出: {"name":null,"age":25}
}
// 需要包含之前定义的 User 类
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
# 6.3 其他常用 GsonBuilder
配置
disableHtmlEscaping()
: 默认 Gson 会对 HTML 字符(如<
,>
,=
等)进行转义。调用此方法可以禁用 HTML 转义。setFieldNamingPolicy(FieldNamingPolicy policy)
: 设置字段命名策略,例如FieldNamingPolicy.LOWER_CASE_WITH_UNDERSCORES
可以自动将 Java 驼峰命名转换为 JSON 下划线命名。registerTypeAdapter(Type type, Object typeAdapter)
: 注册自定义的TypeAdapter
或JsonSerializer
/JsonDeserializer
,用于完全控制特定类型的序列化/反序列化逻辑。addSerializationExclusionStrategy(ExclusionStrategy strategy)
/addDeserializationExclusionStrategy(ExclusionStrategy strategy)
: 添加自定义排除策略。
# 七、实战应用场景
# 7.1 在 Spring Boot 中集成 Gson
虽然 Spring Boot 默认使用 Jackson,但可以通过配置轻松替换为 Gson。
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.Bean;
import org.springframework.http.converter.json.GsonHttpMessageConverter; // 引入 Gson 消息转换器
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
/**
* Spring Boot 应用示例:配置 Gson 作为默认 JSON 处理器
*/
@SpringBootApplication
public class GsonSpringBootApplication {
public static void main(String[] args) {
SpringApplication.run(GsonSpringBootApplication.class, args);
}
/**
* 配置一个自定义的 GsonHttpMessageConverter Bean。
* Spring Boot 会检测到这个 Bean 并优先使用它来处理 HTTP 请求/响应中的 JSON。
* 这会覆盖默认的 Jackson 配置。
*
* @return 配置好的 GsonHttpMessageConverter
*/
@Bean
public GsonHttpMessageConverter gsonHttpMessageConverter() {
// 1. 创建 GsonBuilder 来定制 Gson 实例
GsonBuilder gsonBuilder = new GsonBuilder();
// 2. 配置 Gson (示例配置)
gsonBuilder.setDateFormat("yyyy-MM-dd HH:mm:ss"); // 设置全局日期格式
gsonBuilder.setPrettyPrinting(); // 开发环境下可启用格式化输出
gsonBuilder.serializeNulls(); // 序列化 null 值
// gsonBuilder.excludeFieldsWithoutExposeAnnotation(); // 如果需要 @Expose 支持
// ... 添加更多自定义配置 ...
// 3. 创建配置好的 Gson 实例
Gson gson = gsonBuilder.create();
// 4. 创建 GsonHttpMessageConverter 并设置自定义的 Gson 实例
GsonHttpMessageConverter converter = new GsonHttpMessageConverter();
converter.setGson(gson);
// 5. 返回配置好的转换器 Bean
return converter;
}
// 可以在 Controller 中直接使用 @RequestBody 和 @ResponseBody,
// Spring Boot 会自动使用配置的 GsonHttpMessageConverter 进行转换。
/*
@RestController
public class MyController {
@PostMapping("/users")
public User createUser(@RequestBody User user) {
// ... process user ...
return user; // 返回 User 对象,会被 Gson 序列化为 JSON 响应
}
}
*/
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
在 application.properties
或 application.yml
中,可以通过设置 spring.mvc.converters.preferred-json-mapper=gson
来明确指定优先使用 Gson (如果同时存在 Jackson 和 Gson 依赖)。
# 7.2 处理动态或未知结构的 JSON (树模型)
当 JSON 结构不固定或预先未知时,使用 Gson 的树模型 (JsonElement
, JsonObject
, JsonArray
) 是一个好方法。
import com.google.gson.Gson;
import com.google.gson.JsonElement;
import com.google.gson.JsonObject;
import com.google.gson.JsonArray; // 引入 JsonArray
import com.google.gson.JsonParser; // 引入 JsonParser
import com.google.gson.JsonPrimitive; // 引入 JsonPrimitive
/**
* Gson 示例:使用树模型处理动态结构的 JSON
*/
public class GsonDynamicJsonExample {
public static void main(String[] args) {
// 1. 准备一个结构可能变化的 JSON 字符串
String eventJson = "{"
+ "\"eventType\": \"USER_LOGIN\","
+ "\"timestamp\": 1692520800000,"
+ "\"payload\": {" // payload 结构根据 eventType 可能不同
+ "\"userId\": \"user123\","
+ "\"ipAddress\": \"192.168.1.100\""
+ "}"
+ "}";
String eventJson2 = "{"
+ "\"eventType\": \"ITEM_PURCHASED\","
+ "\"timestamp\": 1692521000000,"
+ "\"payload\": {"
+ "\"itemId\": \"prod789\","
+ "\"quantity\": 2,"
+ "\"price\": 49.99"
+ "}"
+ "}";
// 2. 使用 JsonParser 解析 JSON 字符串为 JsonElement
JsonElement rootElement = JsonParser.parseString(eventJson);
JsonElement rootElement2 = JsonParser.parseString(eventJson2);
// 3. 处理第一个事件 (USER_LOGIN)
processEvent(rootElement);
// 4. 处理第二个事件 (ITEM_PURCHASED)
processEvent(rootElement2);
}
/**
* 根据事件类型动态处理 JsonElement
* @param eventElement 解析后的根 JsonElement
*/
public static void processEvent(JsonElement eventElement) {
if (eventElement.isJsonObject()) {
JsonObject eventObject = eventElement.getAsJsonObject();
// 获取通用字段
String eventType = eventObject.get("eventType").getAsString();
long timestamp = eventObject.get("timestamp").getAsLong();
System.out.println("\n--- 处理事件 ---");
System.out.println("事件类型: " + eventType);
System.out.println("时间戳: " + timestamp);
// 获取 payload 对象
JsonObject payload = eventObject.getAsJsonObject("payload");
// 根据 eventType 动态处理 payload
switch (eventType) {
case "USER_LOGIN":
String userId = payload.get("userId").getAsString();
String ipAddress = payload.get("ipAddress").getAsString();
System.out.println("用户登录信息: userId=" + userId + ", ipAddress=" + ipAddress);
break;
case "ITEM_PURCHASED":
String itemId = payload.get("itemId").getAsString();
int quantity = payload.get("quantity").getAsInt();
double price = payload.get("price").getAsDouble();
System.out.println("物品购买信息: itemId=" + itemId + ", quantity=" + quantity + ", price=" + price);
break;
default:
System.out.println("未知的事件类型,原始 payload: " + payload.toString());
break;
}
} else {
System.err.println("输入的不是有效的 JSON 对象事件结构");
}
}
// 需要 User 类定义 (如果选择将 payload 转为 POJO)
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
输出结果:
--- 处理事件 ---
事件类型: USER_LOGIN
时间戳: 1692520800000
用户登录信息: userId=user123, ipAddress=192.168.1.100
--- 处理事件 ---
事件类型: ITEM_PURCHASED
时间戳: 1692521000000
物品购买信息: itemId=prod789, quantity=2, price=49.99
2
3
4
5
6
7
8
9
总结
Gson 作为 Google 推出的一款成熟且广泛使用的 Java JSON 库,以其简洁直观的 API、对复杂对象和泛型的良好支持以及强大的自定义能力赢得了开发者的青睐。
核心优势与功能回顾:
- 基础转换: 通过
toJson()
和fromJson()
轻松实现 Java 对象与 JSON 字符串的双向转换。 - 无需注解: 对标准 POJO 无需额外注解即可工作,降低了使用门槛。
- 泛型支持: 利用
TypeToken
完美解决了 Java 泛型擦除问题,能够准确地反序列化泛型集合(如List<T>
,Map<K, V>
)。 - 树模型操作: 提供了
JsonElement
,JsonObject
,JsonArray
等类,允许像操作 DOM 一样灵活处理动态或未知结构的 JSON 数据。 - 强大的自定义能力:
GsonBuilder
提供了丰富的配置选项(日期格式、null 值处理、字段命名策略、排除策略、格式化输出等),并支持通过TypeAdapter
实现终极定制。 - 注解支持: 提供了
@SerializedName
,@Expose
等注解,用于更细粒度地控制序列化和反序列化行为。 - 生态整合: 可以方便地集成到 Spring Boot 等主流框架中。
无论是简单的 DTO 转换、处理复杂的 API 响应,还是操作动态 JSON 数据,Gson 都能提供可靠且高效的解决方案。熟练掌握 Gson 的用法,无疑会大大提升 Java 开发中处理 JSON 数据的效率和代码质量。