下面我将为你详细讲解如何实现,从最简单到更复杂的场景,并提供完整的代码示例。

核心思想
这个过程就像“翻译”:
- JSON 字符串:一种通用的、人类可读的数据格式。
- Java 对象:在 Java 语言中定义的、带有特定结构和行为的实体。
你需要一个“翻译官”,这个“翻译官”JSON 库,它会读取 JSON 字符串,并根据你提供的 Java 对象的“结构”(即类的字段),将数据一一对应地填充进去。
第一步:选择一个 JSON 库
目前最主流、最好用的 Java JSON 库是 Jackson 和 Gson,这里我们以 Jackson 为例进行讲解,因为它功能强大、性能优异,并且是 Spring Boot 等框架的默认选择。
如何添加 Jackson 依赖 (Maven)

如果你使用 Maven,在你的 pom.xml 文件中添加以下依赖:
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.15.2</version> <!-- 使用最新的稳定版本 -->
</dependency>
如果你使用 Gradle,在 build.gradle 文件中添加:
implementation 'com.fasterxml.jackson.core:jackson-databind:2.15.2'
第二步:创建与 JSON 结构对应的 Java 类
这是最关键的一步,你的 Java 类的字段名和类型必须与 JSON 中的键和值类型相匹配。
假设我们有这样一个 JSON 字符串:

{
"name": "张三",
"age": 30,
"isStudent": false,
"courses": [
"Java",
"Python"
],
"address": {
"city": "北京",
"street": "中关村大街1号"
}
}
你需要创建一个对应的 Java 类:
// User.java
public class User {
private String name;
private int age;
private boolean isStudent;
private List<String> courses;
private Address address;
// 必须提供一个无参构造函数,Jackson 在反序列化时会使用它
public User() {
}
// 推荐:为每个字段提供 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; }
public boolean isStudent() { return isStudent; } // boolean 类型的 getter 通常是 isXxx()
public void setStudent(boolean student) { isStudent = student; }
public List<String> getCourses() { return courses; }
public void setCourses(List<String> courses) { this.courses = courses; }
public Address getAddress() { return address; }
public void setAddress(Address address) { this.address = address; }
// 可选:重写 toString() 方法,方便打印和调试
@Override
public String toString() {
return "User{" +
"name='" + name + '\'' +
", age=" + age +
", isStudent=" + isStudent +
", courses=" + courses +
", address=" + address +
'}';
}
}
// Address.java
public class Address {
private String city;
private String street;
public Address() {
}
public String getCity() { return city; }
public void setCity(String city) { this.city = city; }
public String getStreet() { return street; }
public void setStreet(String street) { this.street = street; }
@Override
public String toString() {
return "Address{" +
"city='" + city + '\'' +
", street='" + street + '\'' +
'}';
}
}
关键点:
- 字段名:Java 类中的私有字段名需要与 JSON 中的 key 完全一致(Jackson 默认是大小写敏感的),如果不一致,可以通过注解解决(后面会讲)。
- 数据类型:
- JSON
string-> JavaString - JSON
number-> Javaint,long,double等 - JSON
boolean-> Javaboolean - JSON
array-> JavaList,Set或数组 - JSON
object-> Java 自定义的另一个类(如Address)
- JSON
- 无参构造函数:Jackson 在创建对象实例时,会通过反射调用无参构造函数。如果没有它,反序列化会失败。
- Getter/Setter:Jackson 通过调用 setter 方法来设置值,通过 getter 方法来读取值,虽然不是绝对强制(对于
final字段可以直接赋值),但强烈推荐使用标准的 JavaBean 规范(即提供 getter 和 setter)。
第三步:使用 Jackson 进行转换
我们有了 JSON 字符串和对应的 Java 类,就可以进行转换了。
核心类:ObjectMapper
ObjectMapper 是 Jackson 库中所有操作的入口,它负责读取和写入 JSON。
完整代码示例:
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import java.util.Arrays;
public class JsonToJavaExample {
public static void main(String[] args) {
// 1. 创建 ObjectMapper 实例(它线程安全,可以全局共享)
ObjectMapper objectMapper = new ObjectMapper();
// 2. 定义你的 JSON 字符串
String jsonString = "{\n" +
" \"name\": \"张三\",\n" +
" \"age\": 30,\n" +
" \"isStudent\": false,\n" +
" \"courses\": [\n" +
" \"Java\",\n" +
" \"Python\"\n" +
" ],\n" +
" \"address\": {\n" +
" \"city\": \"北京\",\n" +
" \"street\": \"中关村大街1号\"\n" +
" }\n" +
"}";
try {
// 3. 调用 readValue 方法进行转换
// 第一个参数:JSON 字符串
// 第二个参数:要转换成的 Java 对象的 .class 文件
User user = objectMapper.readValue(jsonString, User.class);
// 4. 验证结果
System.out.println("转换成功!");
System.out.println(user.getName()); // 输出: 张三
System.out.println(user.getAge()); // 输出: 30
System.out.println(user.isStudent()); // 输出: false
System.out.println(user.getCourses()); // 输出: [Java, Python]
System.out.println(user.getAddress()); // 输出: Address{city='北京', street='中关村大街1号'}
// 调用我们重写的 toString() 方法,可以更直观地查看整个对象
System.out.println("\n完整对象信息:");
System.out.println(user);
} catch (JsonProcessingException e) {
System.err.println("JSON 解析失败!");
e.printStackTrace();
}
}
}
运行这段代码,你将看到控制台成功打印出了从 JSON 转换而来的 User 对象的信息。
高级场景与常用注解
在实际开发中,JSON 结构和 Java 类名不一定完全匹配,这时就需要使用注解来提供更灵活的映射规则。
场景1:JSON 的 key 和 Java 字段名不同
JSON 中是 user_name,但 Java 类中想用 name。
使用 @JsonProperty 注解:
public class User {
@JsonProperty("user_name") // 告诉 Jackson,JSON 中的 "user_name" 对应这个字段
private String name;
// ... 其他字段
}
场景2:JSON 中有多余的字段
默认情况下,JSON 中有 Java 类中没有的字段,Jackson 会抛出异常,如果希望忽略这些多余的字段:
使用 @JsonIgnoreProperties 注解(在类级别上使用):
@JsonIgnoreProperties(ignoreUnknown = true) // 忽略所有未知属性
public class User {
// ...
}
或者使用 @JsonIgnore 注解(在字段级别上使用),来忽略某个特定字段(即使它在 JSON 中存在,也不映射到 Java 对象)。
场景3:JSON 中缺少某个字段
默认情况下,JSON 中缺少 Java 类中必填的字段,且没有 setter,可能会报错或得到 null,如果希望给字段一个默认值:
使用 @JsonSetter 注解结合 null 判断:
public class User {
private String name = "默认用户"; // 直接在声明时赋默认值
@JsonSetter("name")
public void setName(String name) {
if (name != null) {
this.name = name;
}
// name 为 null,则保持默认值
}
}
场景4:将 JSON 数组转换为 Java List
如果你想将一个 JSON 数组(如 ["Java", "Python"])直接转换成 List<String>,可以这样写:
String jsonArrayString = "[\"Java\", \"Python\"]";
// 注意:这里需要使用 TypeReference 来告诉 Jackson 泛型的具体类型
List<String> courses = objectMapper.readValue(jsonArrayString, new TypeReference<List<String>>() {});
System.out.println(courses); // 输出: [Java, Python]
| 步骤 | 操作 | 关键点 |
|---|---|---|
| 准备库 | 添加 Jackson (或 Gson) 依赖到项目中。 | Maven/Gradle 配置 |
| 定义模型 | 创建 Java 类,使其字段和结构与 JSON 匹配。 | 字段名、类型、无参构造函数、Getter/Setter |
| 执行转换 | 使用 ObjectMapper 的 readValue() 方法。 |
objectMapper.readValue(jsonString, TargetClass.class) |
| 处理异常 | 使用 try-catch 捕获 JsonProcessingException。 |
健壮的代码处理 |
| 高级定制 | 使用 @JsonProperty, @JsonIgnoreProperties 等注解。 |
解决命名不匹配、忽略多余字段等问题 |
掌握了以上步骤,你就可以应对绝大多数 JSON 转 Java 对象的场景了。
