Java学习之——“IO流“的进阶流之序列化流的学习

一、核心概念:什么是序列化与反序列化?

  • 序列化 (Serialization): 将一个对象(在内存中的状态)转换成一个字节序列的过程。这个字节序列包含了对象的数据、对象的类型以及对象中存储的属性等信息。
  • 反序列化 (Deserialization): 将序列化后得到的字节序列恢复为一个对象的过程。

目的

  • 持久化存储:将对象永久地保存到硬盘上的文件中,下次程序启动时可以恢复。
  • 网络传输:将对象通过网络从一个节点传输到另一个节点,例如在 RPC(远程过程调用)、消息队列或分布式系统中。

二、序列化的实现

        Java 中要让一个类的对象能够被序列化,非常简单:只需要让这个类实现 java.io.Serializable 接口即可。Serializable 接口是一个标记接口(Marker Interface),它内部没有任何方法需要实现。它的作用仅仅是“标记”这个类的对象是可序列化的,告诉 Java 虚拟机(JVM):“请注意,我这个类的对象可以被序列化哦!”

示例:定义一个可序列化的类

import java.io.Serializable;// 实现 Serializable 接口
public class Person implements Serializable {// 强烈建议显式声明 serialVersionUIDprivate static final long serialVersionUID = 1L; private String name;private int age;// transient 关键字标记的成员变量不会被序列化private transient String password; // 构造方法、getter、setter 等...public Person(String name, int age, String password) {this.name = name;this.age = age;this.password = password;}@Overridepublic String toString() {return "Person{" +"name='" + name + '\'' +", age=" + age +", password='" + password + '\'' + // 反序列化后 password 会是 null'}';}// ... 省略 getter 和 setter
}

关键点 1:serialVersionUID

  • 是什么:一个类的序列化版本号。用于在反序列化时验证序列化的对象和当前类的版本是否一致。
  • 为什么重要:如果你不显式声明,JVM 会根据类的结构自动生成一个。一旦类的结构发生改变(比如增加了一个字段),自动生成的 serialVersionUID 也会改变,这将导致反序列化失败,抛出 InvalidClassException
  • 最佳实践强烈建议显式声明一个固定的 serialVersionUID(如 1L)。这样即使类后期增加了字段,只是反序列化时新字段为默认值,而不会直接失败,保证了向后兼容性。

关键点 2:transient 关键字

  • 作用:用于修饰成员变量,表示该变量不参与序列化过程。
  • 使用场景:用于保护敏感信息(如密码、密钥等),或者存储一些没必要序列化的临时数据(如缓存、线程句柄等)。

三、序列化流与反序列化流的核心类

Java 提供了两个专门的流来处理对象的序列化和反序列化:

  • ObjectOutputStream: 序列化流,用于将对象写入字节输出流(如文件)。
  • ObjectInputStream: 反序列化流,用于从字节输入流(如文件)中读取并重建对象。

它们通常需要包裹在字节流(如 FileInputStream/FileOutputStream)之上,因为它们的底层操作仍然是字节。

序列化对象(写入文件)
import java.io.*;public class SerializationDemo {public static void main(String[] args) {Person person = new Person("Alice", 30, "secret123");// try-with-resources 确保流正确关闭try (// 1. 创建节点流(字节流),指向目标文件FileOutputStream fos = new FileOutputStream("person.dat");// 2. 创建处理流(序列化流),包裹节点流ObjectOutputStream oos = new ObjectOutputStream(fos)) {// 3. 关键操作:将对象写入(序列化)到文件oos.writeObject(person);System.out.println("对象序列化成功!");} catch (IOException e) {e.printStackTrace();}}
}
反序列化对象(从文件读取)
import java.io.*;public class DeserializationDemo {public static void main(String[] args) {Person person = null;try (// 1. 创建节点流(字节流),连接到源文件FileInputStream fis = new FileInputStream("person.dat");// 2. 创建处理流(反序列化流),包裹节点流ObjectInputStream ois = new ObjectInputStream(fis)) {// 3. 关键操作:读取(反序列化)字节流并重建对象// 需要强制类型转换person = (Person) ois.readObject();System.out.println("对象反序列化成功!");System.out.println(person); // 调用 toString 方法} catch (IOException | ClassNotFoundException e) { // 注意 ClassNotFoundExceptione.printStackTrace();}// 输出:Person{name='Alice', age=30, password='null'}// password 被 transient 修饰,所以反序列化后为 null(默认值)}
}

五、重要注意事项与特性

静态变量不会被序列化

  • 序列化是针对对象实例的,静态变量属于类,不属于任何单个对象,所以不会被序列化。

引用类型的成员变量也必须可序列化

  • 如果一个类有引用类型的成员变量(例如 Person 类里有一个 Address address 字段),那么这个引用类型(Address 类)也必须实现 Serializable 接口,否则整个序列化过程会失败,抛出 NotSerializableException

反序列化不会调用构造方法

  • 对象是通过从流中读取数据并直接赋值来重建的,构造方法不会被调用。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如若转载,请注明出处:http://www.pswp.cn/diannao/98593.shtml
繁体地址,请注明出处:http://hk.pswp.cn/diannao/98593.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

机器学习04——决策树(信息增益、信息增益率、ID3、C4.5、CART、剪枝、连续值缺失值处理)

上一章:机器学习03——线性模型 下一章:机器学习05——多分类学习与类别不平衡 机器学习实战项目:【从 0 到 1 落地】机器学习实操项目目录:覆盖入门到进阶,大学生就业 / 竞赛必备 文章目录一、决策树的基本流程&#…

(论文速读)从语言模型到通用智能体

论文题目:From Multimodal LLMs to Generalist Embodied Agents: Methods and Lessons(从多模式大型语言模型到多面手具身代理:方法和教训)会议:CVPR2025摘要:我们研究了多模态大型语言模型(Multimodal Large Language…

【Epiq Solutions】Matchstiq™ G20 和 Matchstiq™ G40 AI SDR

Matchstiq™ G20 和 Matchstiq™ G40 产品简介 Matchstiq™ G20 和 Matchstiq™ G40 是 Epiq Solutions 推出的 紧凑型、高性能软件定义无线电(SDR)平台,专为满足 严苛 SWaP-C(体积、重量、功耗受限)场景下的战术与移动…

基于Echarts+HTML5可视化数据大屏展示-旅游智慧中心

效果展示&#xff1a; 代码结构&#xff1a;主要代码实现 index.html布局 <!DOCTYPE html> <html lang"en" style"font-size: 97.5px;"> <head><meta http-equiv"Content-Type" content"text/html; charsetUTF-8"…

Docker 镜像的使用

1.镜像的基本信息[roothost1 ~]# docker images REPOSITORY TAG IMAGE ID CREATED SIZE ubuntu latest 802541663949 2 weeks ago 78.1MB hello-world latest 1b44b5a3e06a 4 weeks ago 10.1kB执行 docker images 命令时加上 --no…

网络编程;套接字;TCP通讯;UDP通讯;0909

思维导图TCP服务器端和客户端通讯服务器端 代码#include<myhead.h> #define SER_IP "192.168.109.12"//我的虚拟机的ip #define SER_PORT 8888 int main() {//1.创建一个用于连接的套接字文件描述符int sfd socket(AF_INET,SOCK_STREAM,0);if(sfd-1){perror(&…

贪心算法应用:柔性制造系统(FMS)刀具分配问题详解

Java中的贪心算法应用&#xff1a;柔性制造系统(FMS)刀具分配问题详解 1. 问题背景与定义 柔性制造系统(Flexible Manufacturing System, FMS)是现代智能制造中的关键组成部分&#xff0c;它能够灵活地适应不同产品的生产需求。在FMS中&#xff0c;刀具分配是一个核心优化问题&…

不止是DELETE:MySQL多表关联删除的JOIN语法实战详解

MySQL 的 ​​DELETE​​ 语句用于从数据库表中删除记录。这是一项非常强大且危险的操作&#xff0c;因为一旦执行&#xff0c;数据通常无法恢复。理解其语法和安全实践至关重要。以下是 MySQL 删除语句的详细指南。一、 核心语法&#xff1a;DELETE​​DELETE​​ 语句用于删除…

ubuntu 系統使用過程中黑屏問題分析

背景&#xff1a; 工欲善其事&#xff0c;必先利其器。作为程序员&#xff0c;想要得到更好的发展&#xff0c;遇到问题直接baidu, google 虽然可以得到一些参考或者答案&#xff0c;但是也会降低自己的思考能力&#xff0c;本文以ubuntu 使用过程中黑屏这一问题为背景&#x…

Redis(45)哨兵模式与集群模式有何区别?

Redis 提供了两种高可用性解决方案&#xff1a;哨兵模式和集群模式。它们各自有不同的特点和适用场景。以下是详细的对比和结合代码的示例&#xff1a; 哨兵模式&#xff08;Sentinel&#xff09; 特点高可用性&#xff1a; Sentinel 通过监控、通知、故障转移等功能&#xff0…

微信小程序如何进行分包处理?

目录 分包是什么&#xff1f; 为什么要分包&#xff1f; 分包前后结构对比 具体操作步骤 第 1 步&#xff1a;规划分包结构 第 2 步&#xff1a;修改 app.json 进行配置 第 3 步&#xff1a;创建分包目录并移动文件 第 4 步&#xff1a;处理组件和工具函数的引用 第 5…

Go语言极速入门与精要指南从零到精通的系统化学习路径

&#x1f49d;&#x1f49d;&#x1f49d;欢迎莅临我的博客&#xff0c;很高兴能够在这里和您见面&#xff01;希望您在这里可以感受到一份轻松愉快的氛围&#xff0c;不仅可以获得有趣的内容和知识&#xff0c;也可以畅所欲言、分享您的想法和见解。 持续学习&#xff0c;不断…

git 切换仓库后清理分支缓存

我明白了&#xff0c;从您的截图可以看到远程仓库中有 feature/v1.4_20250903 分支&#xff0c;但本地 git branch -r 看不到&#xff0c;这是因为之前更换过仓库地址后需要重新获取远程仓库的所有信息。让我们执行以下步骤来解决这个问题&#xff1a; 首先执行 git fetch --al…

考研倒计时101天---路由选择协议

路由选择协议&#xff1a;RIP 与 OSPFRIP 协议&#xff08;基于距离向量算法&#xff09;RIP&#xff08;Routing Information Protocol&#xff09;是一种内部网关协议&#xff08;IGP&#xff09;&#xff0c;采用距离向量算法进行路由选择。其主要特点如下&#xff1a;工作机…

「类 vs 实例」对比 ,「类 - 原型 - 实例」的关系

坚持的本身就是意义 目录直观类比类 (Class) vs 实例 (Instance)对比表示例代码类 - 原型 - 实例关系图解释&#xff1a;类 (class Person)原型 (Person.prototype)实例 (new Person(...))总结&#xff1a;直观类比 类&#xff08;Class&#xff09; 图纸 / 模板实例&#xf…

第一课、Cocos Creator 3.8 安装与配置

介绍说明 本文主要介绍在windows系统中&#xff0c;安装开发Cocos使用的软件工具&#xff0c;主要包含&#xff1a;安装CocosDashboard控制面板、CocosCreator3.8编辑器和脚本编辑器 VS Code 。 一、Cocos Dashboard 的安装 说明&#xff1a;Cocos Dashboard 主要作用是能够同…

从航空FACE的一个落地方案漫谈汽车HPC软件架构的思维转变(2/3)FACE的“段”同Autosar的“层”概念区别探索

文章目录PART THREE&#xff1a;段和层的概念比较一、“段”更强调“功能闭环责任归属”&#xff0c;而非“单纯的层级堆叠”二、“段”规避“层”的“刚性依赖陷阱”&#xff0c;适配航空系统的“灵活组合需求”三、“段”贴合航空工业的“工程化语言习惯”&#xff0c;降低跨…

金融量化指标--6InformationRatio信息比率

InformationRatio信息比率计算公式添加图片注释&#xff0c;不超过 140 字&#xff08;可选&#xff09;一、信息比率&#xff08;IR&#xff09;是什么&#xff1f;核心概念&#xff1a;信息比率衡量的是投资组合经理相对于某个基准指数&#xff08;Benchmark&#xff09;&…

Java全栈开发面试实录:从基础到微服务的实战经验分享

Java全栈开发面试实录&#xff1a;从基础到微服务的实战经验分享 一、初识面试场景 我叫李明&#xff0c;28岁&#xff0c;毕业于复旦大学计算机科学与技术专业&#xff0c;硕士学历。在互联网行业已经有5年的工作经验&#xff0c;先后在两家中型互联网公司担任Java全栈开发工程…

【51单片机】【protues仿真】基于51单片机公交报站系统

目录 一、主要功能 二、使用步骤 三、硬件资源 四、软件设计 五、实验现象 一、主要功能 主要功能如下&#xff1a; 1、LCD12864显示时间、日期、公交车车站、温度等 2、按键设置时间&#xff0c;显示公交车信息 3、串口播报相应站点信息 4、按键控制上行、下行、手动播…