Java 里,序列化和反序列化的核心目的就是在“Java 对象”和“可存储/可传输的数据格式”之间转换。

序列化:Java 对象 → 字节流 / JSON 等格式
反序列化:字节流 / JSON 等格式 → Java 对象

1. Java 原生序列化

Java 原生方式通常让类实现 Serializable:

public class User implements Serializable {
 
    private static final long serialVersionUID = 1L;
 
    private Long id;
    private String name;
}

序列化:

User user = new User(1L, "张三");
 
ObjectOutputStream oos =
        new ObjectOutputStream(new FileOutputStream("user.txt"));
 
oos.writeObject(user);
oos.close();

过程:

User对象
   ↓
ObjectOutputStream
   ↓
字节流
   ↓
文件 / 网络

反序列化:

ObjectInputStream ois =
        new ObjectInputStream(new FileInputStream("user.txt"));
 
User user = (User) ois.readObject();
ois.close();

过程:

字节流
   ↓
ObjectInputStream
   ↓
User对象

所以 Java 原生八股可以记:

实现 Serializable 接口,通过 ObjectOutputStream.writeObject() 序列化,通过 ObjectInputStream.readObject() 反序列化。


2. 实际 Java 后端更常见:JSON

你做 Spring Boot 项目时,其实经常已经在进行序列化和反序列化了。

例如前端发送:

{
    "id": 1,
    "name": "张三"
}

Spring Controller:

@PostMapping("/user")
public void addUser(@RequestBody User user) {
}

这里就发生了:

前端 JSON
   ↓
反序列化
   ↓
Java User对象

返回:

@GetMapping("/user")
public User getUser() {
    return new User(1L, "张三");
}

Spring 会把:

Java User对象
   ↓
序列化
   ↓
JSON
   ↓
前端

Spring Boot Web 中常见的是通过 Jackson 完成 JSON 转换。

例如 Jackson 手动写:

ObjectMapper mapper = new ObjectMapper();
 
String json = mapper.writeValueAsString(user);

就是:

Java对象 → JSON

反过来:

User user = mapper.readValue(json, User.class);

就是:

JSON → Java对象

3. Redis 里也会遇到

比如你做 Java + Redis:

User对象
   ↓
序列化
   ↓
JSON / 字节数据
   ↓
Redis

读取:

Redis
 ↓
JSON / 字节数据
 ↓
反序列化
 ↓
User对象

所以 Redis 的 RedisTemplate 中也涉及序列化器的选择,例如字符串序列化、JSON 序列化等。


面试怎么回答

如果面试官问:

Java 中序列化和反序列化一般怎么实现?

你可以回答:

序列化就是把 Java 对象转换成可以存储或者网络传输的数据形式,反序列化就是把这些数据重新转换成 Java 对象。

Java 原生序列化可以让类实现 Serializable 接口,然后通过 ObjectOutputStream 和 ObjectInputStream 完成序列化和反序列化。

不过实际 Java Web 开发中,更常见的是使用 JSON,例如 Spring Boot 通常通过 Jackson 的 ObjectMapper 完成 Java 对象和 JSON 之间的序列化与反序列化;在 Redis、RPC 等场景中也会根据需求使用对应的序列化方式。

你准备实习八股的话,再重点记住一个追问:

** Serializable ** 是一个标记接口,本身没有需要实现的方法。

另外 serialVersionUID、transient、为什么不推荐 Java 原生序列化,这三个也是这道题最容易继续追问的方向。