Java JSON 字符串转对象:从入门到精通,一篇搞定所有场景(附代码)
Meta 描述:
还在为 Java 中如何将 JSON 字符串转换成 Java 对象而烦恼?本文是全网最全面的Java JSON字符串转对象指南,涵盖 Jackson、Gson、Fastjson 三大主流库,从基础配置到高级用法,再到性能对比和避坑指南,手把手带你掌握,让你从此告别转换难题。

引言:为什么 JSON 字符串转对象是 Java 开发者的必备技能?
在现代软件开发中,JSON(JavaScript Object Notation)已成为数据交换的事实标准,无论是 RESTful API 的响应、配置文件,还是消息队列中的数据,我们几乎无处不见它的身影,对于 Java 开发者而言,最常见的需求之一就是:如何将一个 JSON 格式的字符串,转换成一个我们熟悉的 Java 对象(POJO/Model)。
这个过程,我们通常称之为“反序列化”(Deserialization),它的重要性不言而喻:
- 提升效率:直接操作结构化的 Java 对象,远比手动解析字符串要方便、安全且高效。
- 类型安全:编译器可以检查类型错误,避免在运行时才发现因数据类型不匹配导致的异常。
- 代码可读性:将数据映射到业务模型对象,代码逻辑更清晰,更易于维护。
本文将作为你的终极指南,带你系统性地学习在 Java 中实现 JSON 字符串转对象的多种方法,并深入探讨其背后的原理和最佳实践。
第一部分:核心概念与准备工作
在开始编码之前,我们需要明确几个核心概念并准备好开发环境。

什么是 JSON 字符串和 Java 对象?
- JSON 字符串:一个符合 JSON 规范的文本字符串,
{"name":"张三", "age":30, "isEmployee":true, "skills":["Java", "Python"]}。 - Java 对象:由我们自己定义的 Java 类(POJO - Plain Old Java Object)创建的实例,一个
User类的实例。
我们的目标就是将前者“翻译”成后者。
主流 JSON 处理库对比
Java 生态中最流行的 JSON 库有三个,它们各有千秋:
| 库名 | 维护方 | 特点 | 适用场景 |
|---|---|---|---|
| Jackson | FasterXML | 性能卓越、功能强大、社区活跃、Spring Boot 默认集成 | 首选推荐,几乎适用于所有场景,尤其是对性能有要求的 Web 应用。 |
| Gson | API 简洁、易于上手、对复杂泛型支持良好 | Google 系项目,或偏爱简单 API 的开发者。 | |
| Fastjson | 阿里巴巴 | 性能极高、API 丰富(支持 JSONPath 等) | 国内互联网公司常用,但需注意历史版本的安全漏洞问题,建议使用最新版。 |
本文将以 Jackson 为主,Gson 为辅,进行详细讲解,因为它们是社区公认的最稳定、最可靠的选择。
项目环境准备
以 Maven 项目为例,你需要在 pom.xml 中添加相应依赖。

Jackson 依赖:
<dependencies>
<!-- Jackson Core -->
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-core</artifactId>
<version>2.15.2</version> <!-- 建议使用最新稳定版 -->
</dependency>
<!-- Jackson Databind (包含核心和注解功能) -->
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.15.2</version>
</dependency>
</dependencies>
Gson 依赖:
<dependency>
<groupId>com.google.code.gson</groupId>
<artifactId>gson</artifactId>
<version>2.10.1</version> <!-- 建议使用最新稳定版 -->
</dependency>
第二部分:Jackson 篇 - 业界标准的王者用法
Jackson 的核心 API 非常直观,主要依赖于 ObjectMapper 这个类。
基础转换:一对一映射
这是最简单也是最常见的情况,JSON 的键必须与 Java 对象的属性名完全匹配(或通过注解配置)。
步骤:
- 创建一个与 JSON 结构对应的 Java 类(POJO)。
- 创建
ObjectMapper实例。 - 调用
objectMapper.readValue(jsonString, User.class)方法。
代码示例:
a. 定义 Java 类
// User.java
public class User {
private String name;
private int age;
private boolean isEmployee;
// 必须提供无参构造函数,Jackson 在反序列化时会使用它
public User() {
}
// 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 boolean isEmployee() { return isEmployee; }
public void setEmployee(boolean employee) { isEmployee = employee; }
@Override
public String toString() {
return "User{" +
"name='" + name + '\'' +
", age=" + age +
", isEmployee=" + isEmployee +
'}';
}
}
b. 执行转换
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
public class JacksonMain {
public static void main(String[] args) {
String jsonString = "{\"name\":\"李四\", \"age\":28, \"isEmployee\":true}";
ObjectMapper objectMapper = new ObjectMapper();
try {
// 核心代码:将 JSON 字符串转为 User 对象
User user = objectMapper.readValue(jsonString, User.class);
// 验证结果
System.out.println(user.getName()); // 输出: 李四
System.out.println(user.getAge()); // 输出: 28
System.out.println(user.isEmployee()); // 输出: true
System.out.println(user); // 输出: User{name='李四', age=28, isEmployee=true}
} catch (JsonProcessingException e) {
e.printStackTrace();
}
}
}
进阶用法:处理复杂 JSON 结构
现实世界的 JSON 往往更复杂,比如嵌套对象、数组、集合等。
JSON 包含嵌套对象
JSON 字符串:
{
"id": 101,
"username": "admin",
"profile": {
"email": "admin@example.com",
"signupDate": "2025-01-15"
}
}
Java 类设计:
// Profile.java
public class Profile {
private String email;
private String signupDate;
// Getters and Setters...
}
// UserWithProfile.java
public class UserWithProfile {
private int id;
private String username;
private Profile profile; // 嵌套对象
// Getters and Setters...
}
转换代码与基础版完全一致,Jackson 会自动处理嵌套关系。
JSON 包含数组或集合
JSON 字符串:
{
"userId": 500,
"username": "coder",
"skills": ["Java", "Spring Boot", "MySQL"]
}
Java 类设计:
这里必须使用集合接口(如 List),而不是具体实现类(如 ArrayList)。
import java.util.List;
public class UserWithSkills {
private int userId;
private String username;
private List<String> skills; // 使用 List 接口
// Getters and Setters...
}
转换代码同样不变,Jackson 会自动将 JSON 数组转换为 ArrayList。
Jackson 注解:让转换更灵活
当 JSON 键名与 Java 属性名不匹配,或者需要忽略某些字段时,Jackson 的注解就派上用场了。
| 注解 | 作用 | 示例 |
|---|---|---|
@JsonProperty |
指定 JSON 属性名与 Java 属性名的映射 | @JsonProperty("user_name") private String name; |
@JsonIgnore |
在序列化/反序列化时忽略该字段 | @JsonIgnore private String password; |
@JsonIgnoreProperties |
类级别注解,忽略未知的属性 | @JsonIgnoreProperties(ignoreUnknown = true) |
示例:
@JsonIgnoreProperties(ignoreUnknown = true) // 忽略 JSON 中存在但类中没有的属性
public class AdvancedUser {
@JsonProperty("user_id") // 将 JSON 的 "user_id" 映射到 "id" 属性
private int id;
@JsonIgnore // 忽略这个属性,不参与转换
private String internalToken;
// Getters and Setters...
}
第三部分:Gson 篇 - Google 的优雅方案
Gson 的 API 设计得非常“纯面向对象”,它的核心是 Gson 类。
基础转换
Gson 的用法与 Jackson 非常相似,同样需要 POJO 和 Getter/Setter 方法。
代码示例:
import com.google.gson.Gson;
public class GsonMain {
public static void main(String[] args) {
String jsonString = "{\"name\":\"王五\", \"age\":35, \"isEmployee\":false}";
// 创建 Gson 实例
Gson gson = new Gson();
// 核心代码:将 JSON 字符串转为 User 对象
User user = gson.fromJson(jsonString, User.class);
// 验证结果
System.out.println(user.getName()); // 输出: 王五
System.out.println(user.getAge()); // 输出: 35
System.out.println(user.isEmployee()); // 输出: false
}
}
可以看到,Gson 的代码量更少,new Gson() 即可完成初始化,非常轻量。
Gson 的独特优势
Gson 在处理泛型和复杂类型时,API 显得更加优雅。
场景:反序列化为 List<User>
JSON 字符串 (数组形式):
[
{"name":"赵六", "age":40},
{"name":"钱七", "age":22}
]
使用 Jackson:
需要借助 TypeReference 来获取完整的泛型类型信息,否则会丢失类型。
ObjectMapper mapper = new ObjectMapper();
// 使用 TypeReference 来明确指定目标类型
List<User> userList = mapper.readValue(jsonStringString, new TypeReference<List<User>>() {});
使用 Gson:
Gson 提供了 TypeToken 工具类,用法类似但感觉更符合 Java 生态。
import com.google.gson.reflect.TypeToken;
import java.lang.reflect.Type;
import java.util.List;
Gson gson = new Gson();
// 使用 TypeToken 来获取类型
Type userListType = new TypeToken<List<User>>() {}.getType();
List<User> userList = gson.fromJson(jsonString, userListType);
虽然看起来步骤相似,但 TypeToken 是 Gson 处理泛型的标准模式,社区认知度很高。
第四部分:性能对比与选型建议
| 特性 | Jackson | Gson | Fastjson |
|---|---|---|---|
| 性能 | 极快,数据流 API 性能最优 | 快,但通常略逊于 Jackson | 极快,声称是最快的 |
| 功能 | 最全面,模块化设计,支持数据绑定、树模型、流 API | 功能齐全,但模块化不如 Jackson | 功能非常丰富,如 JSONPath 等 |
| 易用性 | API 直观,学习曲线平缓 | API 简洁,非常容易上手 | API 丰富但有时略显复杂 |
| 生态/集成 | Spring Boot 默认,生态最好 | Google 官方,生态稳定 | 国内生态好,但历史有安全坑 |
| 泛型处理 | TypeReference |
TypeToken |
类似 Gson |
选型建议:
- 无脑选 Jackson:如果你在开发一个新的 Spring Boot 项目,或者不确定用哪个,直接选择 Jackson,它性能好、功能强、社区支持最广,是业界最稳妥、最没有争议的选择。
- 选 Gson:如果你的项目是 Google 技术栈,或者你极度偏爱简洁的 API,并且不需要 Jackson 那些高级特性,Gson 是一个非常好的备选。
- 谨慎选 Fastjson:如果你的团队有使用 Fastjson 的丰富经验,并且对性能有极致要求,可以使用,但务必使用最新版本,并密切关注其安全公告,对于新项目,不推荐作为首选。
第五部分:常见问题与避坑指南
-
UnrecognizedPropertyException- 问题:JSON 中有属性,但在 Java 类中找不到对应的字段。
- 解决:在类上添加
@JsonIgnoreProperties(ignoreUnknown = true)注解(Jackson/Gson 均有类似机制)或在配置中开启忽略未知属性。
-
InvalidDefinitionException(no Creators, like default constructor, exist)- 问题:Java 类没有提供无参构造函数,这是 Jackson 反序列化时的硬性要求。
- 解决:确保你的 POJO 类有一个
public的无参构造函数。
-
JsonMappingException(cannot deserialize from Object value)- 问题:数据类型不匹配,JSON 中期望一个字符串,但 Java 字段是
int类型。 - 解决:检查 JSON 数据和 Java 类的字段类型是否一致,可以使用
@JsonFormat等注解进行格式转换。
- 问题:数据类型不匹配,JSON 中期望一个字符串,但 Java 字段是
-
循环引用
- 问题:对象 A 中包含对象 B 的引用,而对象 B 又包含对象 A 的引用,序列化/反序列化时会栈溢出。
- 解决:使用
@JsonIgnore注解在其中一个引用上,或者使用@JsonManagedReference和@JsonBackReference(Jackson)来处理双向关系。
掌握 Java JSON 字符串转对象是每一位 Java 开发者的基本功,本文系统地介绍了业界最主流的 Jackson 和 Gson 库的使用方法,从简单的映射到复杂的嵌套和泛型处理,并提供了性能对比和实用的避坑指南。
核心要点回顾:
- 首选 Jackson:凭借其强大的性能和 Spring 生态的加持,它是大多数场景下的最优解。
- POJO 是基础:确保你的 Java 类有无参构造函数和标准的 Getter/Setter 方法。
- 善用注解:
@JsonProperty、@JsonIgnore等注解是解决 JSON 与 Java 对象结构不匹配的利器。 - 处理复杂类型:当面对
List或泛型时,要使用TypeReference(Jackson) 或TypeToken(Gson) 来明确目标类型。
希望这篇详尽的指南能帮助你彻底攻克“Java JSON 字符串转对象”这一技术点,打开你的 IDE,动手实践一下吧!如果你有任何问题或想分享你的经验,欢迎在评论区留言讨论。
