序列化和反序列化

一、核心概念(用生活例子理解)

想象一下:

  • 你有一个乐高拼好的小汽车(对应程序中的Java 对象 ,比如ChatMessage)。
  • 序列化:把这个乐高小汽车拆成一个个独立的零件,并用清单记录每个零件的位置、形状(→ 把 Java 对象转换成字节流 / JSON 字符串等可存储 / 传输的格式)。
  • 反序列化:根据清单,把零散的乐高零件重新拼成原来的小汽车(→ 把字节流 / JSON 字符串还原成原来的 Java 对象)。
官方定义

表格

操作 核心含义
序列化 (Serialize) 将内存中的对象 (如ChatMessage实例)转换为字节序列 / 字符串(如 JSON),方便存储到文件 / 数据库、或网络传输。
反序列化 (Deserialize) 将存储 / 传输的字节序列 / 字符串 (如数据库里的 JSON)还原为内存中的对象,让程序可以直接使用。

二、为什么需要序列化 / 反序列化?

以你之前的代码场景为例:

  1. 存储需求 :ChatMessage对象是内存中的临时数据,程序重启就会消失。把它序列化成 JSON 字符串存到 MongoDB,就能持久化保存。
  2. 传输需求:如果你的聊天程序是分布式的(比如前端→后端→数据库),对象无法直接在网络中传输,需要序列化成 JSON / 二进制流,传输后再反序列化。
  3. 跨语言交互:JSON 是通用格式,Java 序列化的 JSON 字符串,前端 JavaScript 可以反序列化使用,实现跨语言数据交互。

三、代码示例(直观理解)

以你熟悉的ChatMessage为例,用 Jackson 库演示序列化 / 反序列化:

1. 准备实体类

java

运行

复制代码
import com.fasterxml.jackson.databind.ObjectMapper;
import lombok.Data;

@Data // 简化getter/setter,需要lombok依赖
public class ChatMessage {
    private String memoryId;
    private String content;
    private Long timestamp;
}
2. 序列化(对象 → JSON 字符串)

java

运行

复制代码
public class SerializeDemo {
    public static void main(String[] args) throws Exception {
        // 1. 创建内存中的对象
        ChatMessage message = new ChatMessage();
        message.setMemoryId("mem_123");
        message.setContent("你好,MongoDB!");
        message.setTimestamp(System.currentTimeMillis());

        // 2. 序列化:对象 → JSON字符串(相当于拆乐高)
        ObjectMapper objectMapper = new ObjectMapper();
        String jsonStr = objectMapper.writeValueAsString(message);

        System.out.println("序列化后的JSON:");
        System.out.println(jsonStr);
        // 输出:{"memoryId":"mem_123","content":"你好,MongoDB!","timestamp":1740000000000}
    }
}
3. 反序列化(JSON 字符串 → 对象)

java

运行

复制代码
public class DeserializeDemo {
    public static void main(String[] args) throws Exception {
        // 1. 从数据库/文件中读取的JSON字符串
        String jsonStr = "{\"memoryId\":\"mem_123\",\"content\":\"你好,MongoDB!\",\"timestamp\":1740000000000}";

        // 2. 反序列化:JSON字符串 → 对象(相当于拼乐高)
        ObjectMapper objectMapper = new ObjectMapper();
        ChatMessage message = objectMapper.readValue(jsonStr, ChatMessage.class);

        System.out.println("反序列化后的对象:");
        System.out.println("memoryId: " + message.getMemoryId()); // 输出:mem_123
        System.out.println("content: " + message.getContent());   // 输出:你好,MongoDB!
    }
}

四、常见的序列化格式

  1. JSON :最常用,可读性高、跨语言,你的代码中就是用这种格式(chatMessages.getContent() 是 JSON 字符串)。
  2. XML:老牌格式,可读性高但体积大,现在用得少。
  3. 二进制序列化(Java 原生):把对象转成字节流,体积小但只能 Java 之间使用,不跨语言。
  4. Protobuf:谷歌出品,二进制格式,体积小、效率高,适合高性能传输场景。

总结

  1. 序列化:对象 → 字符串 / 字节流(便于存储 / 传输),核心是 "拆"。
  2. 反序列化:字符串 / 字节流 → 对象(便于程序使用),核心是 "拼"。
  3. 你代码中的 messagesFromJson() 就是典型的反序列化操作,把 MongoDB 中存储的 JSON 字符串还原成ChatMessage对象。
相关推荐
大江东去浪淘尽千古风流人物3 天前
【HexVIO】DSP卸载双目惯性VIO:Hexagon向量化前端与单帧融合调度深度解析
前端·状态模式·slam·dsp·vio·hexagon·移动端加速
吃一碗粉只付一碗钱3 天前
12-给SPA友好的401和403响应
c#·状态模式
sunlifenger4 天前
嵌入式部署,解锁张家港智慧灯杆的“极简组网”密码
科技·状态模式
上火的金鱼妹5 天前
关于多进程sse连接通知的实战
javascript·状态模式·sse
阿俊-全栈开发5 天前
LikeShop 小程序商城首页可配置弹窗的设计与实现(Java + uni-app)
小程序·状态模式·likeshop·likeshop开源商城
lingyubb5 天前
配音工具怎么选?从 TTS 合成链路看 6 个可量化参数
状态模式
平头哥技术团队7 天前
从预订问到退房:一间山野民宿的数字人「旅程地图」——Theme07_Homestay.vue 端到端拆解
状态模式·数字人
未来之窗软件服务8 天前
web网络请求竞态问题与取消方案-东方仙盟
前端·状态模式·仙盟创梦ide·东方仙盟·网络取消
一级新生9 天前
多智能体协作:常用协作模式详解
人工智能·状态模式·agent·多智能体·智能体
喜欢打篮球的普通人11 天前
LLVM 前端与优化层:Clang 如何把 C 代码变成 IR
c语言·前端·状态模式