Gson使用手册
Gson 是 Google 提供的一个开源 Java 库,用于将 Java 对象与 JSON(JavaScript Object Notation)格式进行相互转换。它功能强大、使用简单、性能优异,是 Java 开发中处理 JSON 数据的常用工具之一。
本文将详细介绍如何使用 Gson 完成常见的序列化(Java -> JSON)和反序列化(JSON -> Java)操作。
1. 准备工作
首先,确保你的项目中引入了 Gson 依赖。
Maven:
<dependency>
<groupId>com.google.code.gson</groupId>
<artifactId>gson</artifactId>
<version>2.10.1</version>
</dependency>
Gradle:
implementation 'com.google.code.gson:gson:2.10.1'
创建一个 Gson
实例(通常可以创建一个全局的 Gson
对象,或使用 new Gson()
):
import com.google.gson.Gson;
Gson gson = new Gson();
// 或者使用 GsonBuilder 进行更复杂的配置
// Gson gson = new GsonBuilder().setPrettyPrinting().create();
2. 将 Java 对象序列化为 JSON 字符串
使用 gson.toJson(Object)
方法。
class User {
private String name;
private int age;
private boolean isStudent;
// 构造函数、Getter、Setter (Gson 通过反射访问字段,不一定需要 Getter/Setter,但建议提供)
public User(String name, int age, boolean isStudent) {
this.name = name;
this.age = age;
this.isStudent = isStudent;
}
// ... Getter 和 Setter 省略 ...
@Override
public String toString() {
return "User{name='" + name + "', age=" + age + ", isStudent=" + isStudent + "}";
}
}
// 序列化
User user = new User("张三", 25, true);
Gson gson = new Gson();
String jsonString = gson.toJson(user);
System.out.println(jsonString);
// 输出: {"name":"张三","age":25,"isStudent":true}
3. 将 JSON 字符串反序列化为 Java 对象
使用 gson.fromJson(String, Class<T>)
方法。
String jsonString = "{\"name\":\"李四\",\"age\":30,\"isStudent\":false}";
Gson gson = new Gson();
User user = gson.fromJson(jsonString, User.class);
System.out.println(user);
// 输出: User{name='李四', age=30, isStudent=false}
4. 将 JSON 字符串转为 List 集合
当 JSON 是一个数组时,需要使用 TypeToken
来获取泛型类型信息,因为 Java 的泛型在运行时会被擦除。
import com.google.gson.reflect.TypeToken;
import java.lang.reflect.Type;
import java.util.List;
String jsonArrayString = "[{\"name\":\"Alice\",\"age\":28,\"isStudent\":true},{\"name\":\"Bob\",\"age\":32,\"isStudent\":false}]";
// 创建 TypeToken 来指定 List<User> 类型
Type listType = new TypeToken<List<User>>(){}.getType();
Gson gson = new Gson();
List<User> userList = gson.fromJson(jsonArrayString, listType);
for (User u : userList) {
System.out.println(u);
}
// 输出: User{name='Alice', age=28, isStudent=true}
// User{name='Bob', age=32, isStudent=false}
5. 将 List 集合转为 JSON 字符串
使用 gson.toJson(Object)
,Gson 会自动处理 List
。
List<User> users = Arrays.asList(
new User("王五", 22, true),
new User("赵六", 27, false)
);
String jsonArrayString = gson.toJson(users);
System.out.println(jsonArrayString);
// 输出: [{"name":"王五","age":22,"isStudent":true},{"name":"赵六","age":27,"isStudent":false}]
6. 将 JSON 字符串转为 Map
同样,对于 Map
这种泛型集合,需要使用 TypeToken
。
import java.util.Map;
String jsonString = "{\"name\":\"张三\",\"age\":25,\"city\":\"北京\"}";
// 创建 TypeToken 指定 Map<String, Object> 类型
Type mapType = new TypeToken<Map<String, Object>>(){}.getType();
Gson gson = new Gson();
Map<String, Object> map = gson.fromJson(jsonString, mapType);
System.out.println("姓名: " + map.get("name"));
System.out.println("年龄: " + map.get("age"));
System.out.println("城市: " + map.get("city"));
// 遍历
map.forEach((key, value) -> System.out.println(key + ": " + value));
// 注意: 基本数值 (如 age) 默认解析为 Double, Long 等 Number 子类。
7. 将 Map 转为 JSON 字符串
使用 gson.toJson(Object)
。
Map<String, Object> map = new HashMap<>();
map.put("product", "笔记本电脑");
map.put("price", 8999.99);
map.put("inStock", true);
Gson gson = new Gson();
String jsonString = gson.toJson(map);
System.out.println(jsonString);
// 输出: {"product":"笔记本电脑","price":8999.99,"inStock":true}
8. 将 JSON 字符串转为数组
对于对象数组,可以直接指定数组类型。对于基本类型数组,也可以直接指定。
// JSON 字符串转为 User[] 数组
String jsonArrayString = "[{\"name\":\"Charlie\",\"age\":26},{\"name\":\"Diana\",\"age\":29}]";
User[] userArray = gson.fromJson(jsonArrayString, User[].class);
for (User u : userArray) {
System.out.println(u);
}
// 输出: User{name='Charlie', age=26}
// User{name='Diana', age=29}
// JSON 字符串转为 int[] 数组
String intArrayJson = "[1, 2, 3, 4, 5]";
Gson gson = new Gson();
int[] intArray = gson.fromJson(intArrayJson, int[].class);
System.out.println(Arrays.toString(intArray)); // 输出: [1, 2, 3, 4, 5]
9. 将数组转为 JSON 字符串
使用 gson.toJson(Object)
。
User[] users = {new User("Eve", 24, true), new User("Frank", 31, false)};
String jsonArrayString = gson.toJson(users);
System.out.println(jsonArrayString);
// 输出: [{"name":"Eve","age":24,"isStudent":true},{"name":"Frank","age":31,"isStudent":false}]
// int[] 转 JSON
int[] numbers = {10, 20, 30};
Gson gson = new Gson();
String jsonNumbers = gson.toJson(numbers);
System.out.println(jsonNumbers); // 输出: [10,20,30]
重要注意事项与高级配置
TypeToken
的必要性: 当反序列化的目标类型包含泛型(如List<T>
,Map<K, V>
)时,必须使用new TypeToken<YourType>(){}.getType()
。这是为了在运行时保留泛型信息。null
值处理: 默认情况下,Gson 在序列化时会忽略值为null
的字段。如果需要序列化null
值,可以使用GsonBuilder
:Gson gson = new GsonBuilder().serializeNulls().create();
- 字段命名策略: 如果 Java 字段名与 JSON 键名不同,可以使用
@SerializedName
注解。class User { @SerializedName("user_name") private String name; // ... }
- 日期格式化: 可以使用
GsonBuilder
配置日期格式。Gson gson = new GsonBuilder() .setDateFormat("yyyy-MM-dd HH:mm:ss") .create();
transient
关键字: 被transient
修饰的字段默认不会被 Gson 序列化和反序列化。- 性能:
Gson
实例是线程安全的,建议创建一个全局的Gson
实例重复使用,而不是每次都new Gson()
。 - 无参构造函数: Gson 在反序列化创建对象时,需要目标类有一个无参构造函数(可以是
private
的)。
总结
Gson 提供了简洁而强大的 API 来处理 Java 与 JSON 之间的转换。掌握 toJson
和 fromJson
两个核心方法,以及在处理泛型集合时使用 TypeToken
,就能满足绝大多数开发需求。结合 GsonBuilder
进行配置,可以应对更复杂的场景。