当前位置: 首页 > news >正文

【Java序列化与反序列化详解】

Java序列化与反序列化详解

一、序列化与反序列化的核心概念(魔法盒子比喻)

想象你要把一个神奇的魔法盒子寄给远方的朋友。这个魔法盒子里装着各种奇妙的东西(就像Java对象里包含各种数据和状态),但是邮局规定只能寄送扁平的、没有生命的包裹。

这时候,你需要把魔法盒子拆解成一片片扁平的零件(把Java对象转化为字节序列),才能顺利寄出——这个过程就像是Java中的序列化

当你的朋友收到这些扁平的零件后,要按照一定的规则把它们重新组装成原来那个神奇的魔法盒子(把字节序列恢复成Java对象)——这就好比是反序列化

二、序列化

在Java里,序列化就是把Java对象变成一连串的字节,这样就能把这个对象保存到文件里,或者通过网络发送给别的地方。

为什么需要序列化?

比如你写了一个程序,程序里有个对象记录了用户的各种信息(用户名、等级、积分等)。若想把这个用户信息保存下来(下次程序启动还能用),或发给别的服务器处理,就需要先把这个对象变成字节序列。

1. 序列化的前提:实现Serializable接口

要让一个类的对象能够被序列化,这个类必须实现 java.io.Serializable 接口。这个接口就像是一个“许可证”,告诉Java虚拟机“这个类的对象可以被序列化”。

示例代码:

import java.io.Serializable;public class User implements Serializable {private String username;private int level;private int points;public User(String username, int level, int points) {this.username = username;this.level = level;this.points = points;}
}

上述User类实现了Serializable接口,其对象可被序列化。

2. 序列化的实现:ObjectOutputStream

通过 ObjectOutputStream 类完成序列化操作,例如将User对象保存到文件:

import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectOutputStream;public class SerializeExample {public static void main(String[] args) {User user = new User("Alice", 5, 100);try (ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("user.ser"))) {oos.writeObject(user); // 将对象写入文件(转化为字节序列)} catch (IOException e) {e.printStackTrace();}}
}

代码逻辑:创建User对象 → 用ObjectOutputStream将对象写入user.ser文件 → 完成“对象→字节序列”的转换。

三、反序列化

反序列化和序列化相反,是把之前保存的字节序列再变回Java对象。

反序列化的实现:ObjectInputStream

通过 ObjectInputStream 类完成反序列化操作,例如从文件读取User对象:

import java.io.FileInputStream;
import java.io.IOException;
import java.io.ObjectInputStream;public class DeserializeExample {public static void main(String[] args) {try (ObjectInputStream ois = new ObjectInputStream(new FileInputStream("user.ser"))) {// 从文件读取字节序列,还原为User对象User user = (User) ois.readObject();// 正常使用还原后的对象System.out.println("Username: " + user.username);System.out.println("Level: " + user.level);System.out.println("Points: " + user.points);} catch (IOException | ClassNotFoundException e) {e.printStackTrace();}}
}

代码逻辑:用ObjectInputStream读取user.ser的字节序列 → 转换为User对象 → 像普通对象一样调用属性/方法。

四、相关知识要点

1. 版本控制:serialVersionUID(序列化ID)

serialVersionUID 就像是对象的“版本号”,核心作用是避免反序列化失败:

  • 当类的结构发生变化(如增加/删除字段),若serialVersionUID不变,Java会认为“前后是同一个类”,可能因结构不匹配导致反序列化失败;
  • 若手动指定serialVersionUID,类结构变化时更新该值,可明确告诉Java“类已升级”,避免歧义;
  • 若不手动指定,Java会根据类结构自动生成,但自动生成的结果不稳定(如字段顺序变化会导致ID变化),因此建议手动指定

示例(添加serialVersionUID):

import java.io.Serializable;public class User implements Serializable {// 手动指定序列化IDprivate static final long serialVersionUID = 1L;private String username;private int level;private int points;// 构造方法、getter/setter...
}

2. 瞬态变量:transient关键字

transient 修饰的变量不会被序列化,反序列化后会恢复为该类型的默认值(如int默认0,String默认null)。

适用场景:临时计算的字段(无需保存,反序列化后可重新计算)。

示例(transient修饰临时字段):

import java.io.Serializable;public class User implements Serializable {private static final long serialVersionUID = 1L;private String username;private int level;// 临时字段,不序列化private transient int temporaryValue;public User(String username, int level, int temporaryValue) {this.username = username;this.level = level;this.temporaryValue = temporaryValue;}
}

逻辑:temporaryValue不会被写入user.ser → 反序列化后,temporaryValue的值为0(int默认值)。

五、为什么要序列化?(详细场景)

1. 保存和恢复数据

  • 类比场景:玩角色扮演游戏时,关机前保存进度(角色生命值、等级、道具等),下次开机可继续游戏;
  • Java场景:程序运行时的对象包含重要数据(如记账程序的用户收支记录、账户余额),序列化可将这些对象保存到文件;程序重启后,通过反序列化还原对象,数据不丢失。

2. 在网络上传输数据

  • 类比场景:联机游戏中,你的角色信息(等级、道具)需通过网络发给朋友的电脑,网络仅支持“字节序列”传输;
  • Java场景:电商网站的服务器将商品信息(Java对象)序列化 → 通过网络传给客户端 → 客户端反序列化后展示商品详情;分布式系统中,不同服务间的对象传递也依赖序列化。

3. 跨平台和跨语言交互

  • 类比场景:你用Java开发的游戏,想和朋友用Python开发的游戏交换数据,需一种“通用数据格式”;
  • Java场景:序列化将Java对象转为通用字节序列,其他语言(如Python、Go)可解析该字节序列,还原为对应语言的对象;企业开发中,Java后端与Python数据处理脚本的交互常用此方式。

4. 缓存数据

  • 类比场景:游戏中常用的资源(如地图、角色模型)存到缓存,避免每次重新加载;
  • Java场景:对计算复杂或高频使用的对象(如天气查询程序的天气数据),序列化后存入缓存(如Redis,缓存数据本质是字节);下次使用时直接从缓存反序列化,无需重新计算,提升程序效率。

总结

序列化与反序列化是Java中“对象存储与传输”的核心机制:

  • 序列化:ObjectOutputStream + Serializable → 对象→字节序列;
  • 反序列化:ObjectInputStream → 字节序列→对象;
  • 关键注意点:serialVersionUID(版本控制)、transient(排除临时字段);
  • 核心价值:支持数据持久化、网络传输、跨语言交互、缓存优化,是复杂Java程序(如分布式系统、客户端/服务器应用)的基础能力。
http://www.dtcms.com/a/491796.html

相关文章:

  • JAiRouter v1.0.0 正式发布:企业级 AI 服务网关的开源解决方案
  • HDR Scattering and Tone Mapping
  • 做我的世界皮肤壁纸的网站工业设计软件上市公司
  • 网站备案模板自己做的网站可以发布吗
  • vue-easy-tree树状结构
  • 重庆网站设计公司小白测评做网站
  • 可以发布广告的网站农村网站建设补助
  • 哪个网站做的简历最好专业网站设计力荐亿企邦
  • 轻量云服务器Lighthouse × 1Panel Halo 开启创意新玩法,建站与服务部署全攻略
  • 亦庄附近的网站建设公司关键词排名怎么查
  • 做网站建设的利润南宁做企业网站
  • 群体稳定性指标PSI:机器学习模型稳定性评估的核心工具
  • **标题:发散创新:探索自愈系统的设计与实现**引言:随着计算机技术的飞速发展,软件系统的可靠性和稳定性问题愈发受到关注。本文将
  • 常驻服务问答
  • 龙岩建网站公司手机网站建设公司
  • Flink性能调优基石:资源配置与内存优化实践
  • h5页面制作流程抖音seo搜索优化
  • 自己动手做网站公司网页网站建设ppt模板
  • 图片渐变透明,图片透明渐变,图片怎么渐变透明,颜色渐变透明,颜色透明渐变,怎么让图片渐变透明,图片边缘渐变透明,图片渐变半透明
  • 数据产品(3)-数据中台
  • STM32理论 —— 存储、中断
  • 如何选择做网站软件制作
  • 营销型网站建设广州搭建 网站 模版
  • 在NumPy中合并两个一维数组的多种方法
  • 如何求「加减 value 任意次后的最大 MEX」同余类求解
  • 『 数据库 』MySQL复习 - MySQL表CRUD操作全解析
  • 规范门户网站建设虚拟主机可以干什么
  • 完整博客教程:使用Lamini和Hugging Face进行大语言模型微调
  • HandlerThread是什么?为什么它会存在?
  • LeetCode 面试经典 150_栈_有效的括号(52_20_C++_简单)(栈+哈希表)