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

Java序列化

Java序列化

简单来说:

序列化是将对象的状态信息转换为可以存储或传输的形式(如字节序列)的过程。在 Java 中,通过序列化可以把一个对象保存到文件、通过网络传输到其他地方或者存储到数据库等。最直接的原因就是某些场景下需要使用这种数据状态,像网络中不能传输数据,某些存储场景。在java中常见使用,就是实现Serializable接口,而不想被序列化的字段处理方法使用transient关键字就可以了

推荐文章:为什么网络中不能直接传输数据

为什么在网络中不能直接传输数据_在网络通信中,除了文本和二进制数据,其他的数据都无法传输-CSDN博客

1. Java 中序列化的定义与作用
  • 定义:序列化是将对象的状态信息转换为可以存储或传输的形式(如字节序列)的过程。在 Java 中,通过序列化可以把一个对象保存到文件、通过网络传输到其他地方或者存储到数据库等。例如,在分布式系统中,一个对象可能需要从一个节点传输到另一个节点,此时就需要将对象序列化。

  • 原理:Java 序列化机制会自动处理对象的成员变量。当对一个对象进行序列化时,Java 会递归地将对象的非静态和非瞬态(transient)成员变量转换为字节序列。这些字节序列包含了对象的类型信息和成员变量的值等内容。例如,对于一个包含姓名和年龄的Person类对象,序列化后字节序列会包含表示Person类的信息以及姓名和年龄的值的信息。

  • 应用场景:

    • 持久化存储:将对象保存到文件系统中,以便以后可以恢复对象的状态。例如,游戏中的玩家存档,玩家的角色信息(等级、装备等)可以通过序列化存储到本地文件,下次游戏时再读取并恢复。

    • 网络传输:在分布式应用或远程调用(如 Java RMI)中,对象需要在不同的主机之间传输。例如,在一个基于微服务架构的电商系统中,订单信息对象可能需要从订单服务传输到库存服务,这就需要对订单信息对象进行序列化。

2. 不想被序列化的字段处理方法(使用transient关键字)
  • transient关键字的作用:当一个成员变量被声明为transient时,在序列化过程中这个变量将不会被包含在序列化后的字节序列中。例如,对于一个包含密码字段的User类,如果不想将密码序列化(因为安全原因),可以将密码字段声明为transient

  • 示例代码:

     import java.io.Serializable;class Student implements Serializable {private String name;private transient int score;public Student(String name, int score) {this.name = name;this.score = score;}public String getName() {return name;}public int getScore() {return score;}}
    • 假设有一个Student类,其中有一个成绩字段不想被序列化。

      - 在这个例子中,`Student`类实现了`Serializable`接口,表示这个类的对象可以被序列化。`score`字段被声明为`transient`,所以当对`Student`对象进行序列化时,`score`字段的值不会被保存到序列化后的字节序列中。在反序列化时,`transient`字段会被初始化为默认值(对于基本类型,如`int`,默认值为0)。

3. 为什么使用序列化

对象持久化保存

  • 在很多应用场景中,需要将对象的状态长期保存下来。例如,在一个企业级的资源管理系统中,用户的配置信息、系统的状态快照等都需要保存到文件或者数据库中,以便在下次启动程序或者系统恢复时能够重新加载这些信息。序列化提供了一种简单有效的方式来将对象转换为字节序列,这样就可以方便地存储到磁盘上。如果没有序列化,要将复杂的对象存储起来会非常复杂,可能需要手动将每个属性的值逐个提取出来并按照特定的格式写入文件,而序列化机制自动完成了这个复杂的过程。

网络通信的需要

  • 网络确实不能直接传输像 Java 对象这种复杂的数据结构。网络通信协议通常是基于字节流或者消息包来传输数据的。当需要在不同的计算机系统或者进程之间传递对象时,就必须先将对象序列化。例如,在一个分布式的微服务架构中,一个服务需要调用另一个服务的方法并传递一些业务对象作为参数,这些对象必须被序列化后通过网络传输到目标服务,目标服务再将字节序列反序列化回对象,这样才能进行正常的业务处理。

跨平台和跨语言交互

  • 序列化后的字节序列可以在不同的平台和语言环境下进行传输和处理。有些序列化格式(如 JSON、XML)是跨语言兼容的。例如,一个 Java 服务可以将一个对象序列化为 JSON 格式的字节序列,这个字节序列可以被 Python 服务接收并反序列化,这样就实现了不同语言编写的服务之间的交互。这种跨平台和跨语言的特性使得序列化在分布式系统和异构系统集成中非常重要。

缓存系统的应用

  • 在缓存系统中,对象经常需要被存储和检索。序列化允许将对象以一种适合缓存存储的形式(如字节序列)存入缓存中。例如,在一个 Web 应用的缓存系统中,经常需要缓存一些复杂的业务对象(如用户信息、商品详情等),通过序列化可以方便地将这些对象存入像 Redis 这样的缓存中,当需要使用时再反序列化出来,提高了系统的性能和响应速度。

4. 怎么序列化
  1. 实现Serializable接口

    • 接口介绍:在 Java 中,要使一个类可序列化,首先要让这个类实现java.io.Serializable接口。这个接口是一个标记接口,没有任何方法需要实现,它的作用是告诉 Java 虚拟机(JVM)这个类的对象可以被序列化。例如,假设有一个简单的Person类,包含姓名和年龄两个属性:

       import java.io.Serializable;class Person implements Serializable {private String name;private int age;public Person(String name, int age) {this.name = name;this.age = age;}public String getName() {return name;}public int getAge() {return age;}}

    - **注意事项**:实现`Serializable`接口只是第一步,当类的结构发生变化(如添加或删除成员变量、修改成员变量的类型等)时,可能会影响序列化和反序列化的兼容性。为了更好地控制序列化过程,还可以定义一个`serialVersionUID`(序列化版本号)。这个版本号是一个`long`型的常量,用于标识类的序列化版本。如果在反序列化时,类的`serialVersionUID`与序列化时的版本号不一致,可能会导致`InvalidClassException`异常。例如,可以在`Person`类中添加版本号:```javaimport java.io.Serializable;class Person implements Serializable {private static final long serialVersionUID = 1L;// 后续代码同前}

  1. 使用ObjectOutputStream进行序列化

    • 基本步骤:要将一个对象序列化到文件中,可以使用ObjectOutputStream类。首先创建一个文件输出流(FileOutputStream),然后将其包装成ObjectOutputStream

      。接着,使用ObjectOutputStream的writeObject方法将对象写入到输出流中。例如,将Person对象序列化到文件:

       import java.io.FileOutputStream;import java.io.ObjectOutputStream;import java.io.IOException;public class SerializeExample {public static void main(String[] args) {try {Person person = new Person("Alice", 30);FileOutputStream fileOut = new FileOutputStream("person.ser");ObjectOutputStream out = new ObjectOutputStream(fileOut);out.writeObject(person);out.close();fileOut.close();System.out.println("对象已序列化到文件");} catch (IOException e) {e.printStackTrace();}}}
    - **工作原理**:`ObjectOutputStream`在序列化对象时,会递归地处理对象的非静态和非瞬态(`transient`)成员变量。它会将对象的类型信息和成员变量的值按照特定的格式转换为字节序列,并写入到输出流中。如果对象的成员变量也是可序列化的对象,`ObjectOutputStream`会同样地对这些成员变量进行序列化。​3. **从序列化数据中恢复对象(反序列化)**- **基本步骤**:使用`ObjectInputStream`类从序列化的数据中恢复对象。首先创建一个文件输入流(`FileInputStream`),然后将其包装成`ObjectInputStream`。接着,使用`ObjectInputStream`的`readObject`方法从输入流中读取对象。例如,从之前序列化的文件中读取`Person`对象:```javaimport java.io.FileInputStream;import java.io.ObjectInputStream;import java.io.IOException;public class DeserializeExample {public static void main(String[] args) {try {FileInputStream fileIn = new FileInputStream("person.ser");ObjectInputStream in = new ObjectInputStream(fileIn);Person person = (Person) in.readObject();in.close();fileIn.close();System.out.println("姓名:" + person.getName() + ",年龄:" + person.getAge());} catch (IOException | ClassNotFoundException e) {e.printStackTrace();}}}

  • 工作原理ObjectInputStream会读取字节序列,并根据其中包含的类型信息和成员变量的值,重新构建对象。它会按照序列化时的顺序和规则,将字节序列转换回对象的状态。如果在反序列化过程中遇到类的定义发生变化(如添加或删除成员变量),可能需要特殊的处理来确保对象能够正确地恢复。

相关文章:

Java序列化

Java序列化 简单来说: 序列化是将对象的状态信息转换为可以存储或传输的形式(如字节序列)的过程。在 Java 中,通过序列化可以把一个对象保存到文件、通过网络传输到其他地方或者存储到数据库等。最直接的原因就是某些场景下需要…...

基坑表面位移沉降倾斜自动化监测 非接触式一体化解决机器视觉

基于变焦视觉位移监测仪的基坑自动化监测新方案是一种集成了光学、机械、电子、边缘计算、AI识别以及云平台软件等技术的自动化系统。该方案利用变焦机器视觉原理,结合特殊波段成像识别技术和无源靶标,实现了非接触式大空间、多断面、多测点的高精度水平…...

提升效率:精通Windows命令行的艺术

文章目录 引言1. 基本目录操作命令dir:列出目录内容cd:更改目录mkdir 和 rmdir:创建和删除目录 2. 文件操作命令copy:复制文件或目录move:移动或重命名文件/目录del:删除文件 3. 文件查看命令type&#xff…...

ESP32-S3-devKitC-1 点亮板上的WS2812 RGB LED

ESP32-S3-devKitC-1 板上自带了一个RGB LED,型号为 WS2812。 RGB LED 在板上的位置如下图所示。 为了点亮这个WS2812,需要确定这颗RGB LED连接到哪个GPIO上了。 下面是确定GPIO管脚的过程: 1、根据原理图 2、根据PCB布局图: 程…...

python调用matlab函数(内置 + 自定义) —— 安装matlab.engine

文章目录 一、简介二、安装matlab.engine2.1、基于 CMD 安装2.2、基于 MATLAB 安装(不建议) 三、python调用matlab函数(内置 自定义) 一、简介 matlab.engine(MATLAB Engine API for Python):…...

CAD c# 生成略缩图预览

代码如下: using (Transaction tr currentdb.TransactionManager.StartTransaction()){//当前数据库开启事务using (Database tempdb new Database(false, true)) //创建临时数据库(两个参数:是否创建符号表,不与当前文档关联){try{Bitmap …...

端点鉴别、安全电子邮件、TLS

文章目录 端点鉴别鉴别协议ap 1.0——发送者直接发送一个报文表明身份鉴别协议ap 2.0——ap1.0 的基础上,接收者对报文的来源IP地址进行鉴别鉴别协议ap 3.0——使用秘密口令,口令为鉴别者和被鉴别者之间共享的秘密鉴别协议ap 3.1——对秘密口令进行加密&…...

汽车电子元件的可靠性保障:AEC-Q102认证

AEC-Q102标准的起源与价值 随着汽车电子系统的日益复杂,电子器件必须能够在极端的温度、湿度、振动和电磁干扰等恶劣条件下保持性能。AEC-Q102标准由汽车电子委员会(AEC)制定,专门针对LED、激光二极管和光电二极管等光电器件&…...

主成分分析法大全(包括stata+matlab)

数据简介:主成分分析(Principal Component Analysis,PCA), 是一种统计方法。通过正交变换将一组可能存在相关性的变量转换为一组线性不相关的变量,转换后的这组变量叫主成分。在实际课题中,为了…...

ubuntu+ros新手笔记(五):初探anaconda+cuda+pytorch

深度学习三件套:初探anacondacudapytorch 系统ubuntu22.04 1.初探anaconda 1.1 安装 安装过程参照【详细】Ubuntu 下安装 Anaconda 1.2 创建和删除环境 创建新环境 conda create -n your_env_name pythonx.x比如我创建了一个名为“py312“的环境 conda cre…...

C++ List(双向链表)

是一个线性链表结构,它的数据由若干个节点构成,每一个节点都包括一个 信息块(即实际存储的数据)、一个前驱指针和一个后驱指针。它无需分配指定 的内存大小且可以任意伸缩,这是因为它存储在非连续的内存空间中&#…...

ASP.NET|日常开发中读写TXT文本详解

ASP.NET|日常开发中读写TXT文本详解 前言一、读取 TXT 文本1.1 使用StreamReader类 二、写入 TXT 文本2.1 使用StreamWriter类 三、文件编码问题3.1 常见编码格式 四、错误处理和性能考虑4.1 错误处理4.2 性能考虑 结束语优质源码分享 ASP.NET|日常开发中…...

【机器学习】在不确定的光影中:机器学习与概率论的心灵共舞

文章目录 概率与统计基础:解锁机器学习的数据洞察之门前言一、概率论基础1.1 概率的基本概念与性质1.1.1 概率的定义1.1.2 样本空间与事件1.1.3 互斥事件与独立事件1.1.4 概率的计算方法 1.2 条件概率与独立性1.2.1 条件概率1.2.2 独立事件 1.3 随机变量1.3.1 随机变…...

【论文笔记】Editing Models with Task Arithmetic

🍎个人主页:小嗷犬的个人主页 🍊个人网站:小嗷犬的技术小站 🥭个人信条:为天地立心,为生民立命,为往圣继绝学,为万世开太平。 基本信息 标题: Editing Models with Task…...

ESP32外设学习部分--UART篇

前言 在我们学习嵌入式的过程中,uart算是我们用的非常多的一个外设了,我们可以用串口打印信息,也可以用于设备通信,总之串口的作用非常多,我们也非常有必要熟练地去掌握这个外设。 uart的配置 uart的参数配置 uart_…...

ssm-day04 mybatis

mybatis是一个持久层框架,针对的是JDBC的优化 简化数据库操作,能进行单表、多表操作,在这个框架下,需要我们自己写SQL语句 Mapper接口和MapperXML文件就相当于Dao和Dao层的实现 通常将xml文件放在resources包下 ,放在…...

es中段是怎么合并的

文章目录 1. 段合并的背景2. 合并的方式2.1TieredMergePolicy 的层次结构2.2 层次的基本规则2.3 如何理解层次(tier)2.4. 合并过程中的层次示例2.5. TieredMergePolicy 的优势2.6. 小结 3. 合并过程中的优化4. 合并的性能考虑5. 使用 API 手动合并6. 合并…...

5、可暂停的线程控制模型

一、需求 在做播放器的时候,很多的模块会创建一个线程,然后在这个线程上跑单独的功能,同时,需要对这个线程进行控制,比如暂停,继续等,如播放器的解码,解封装等,都需要对…...

sql优化--mysql隐式转换

sql隐式转换 在SQL中,隐式转换是数据库自动进行的类型转换,隐式转换可以帮助我们处理不同类型的数据。 比如,数据表的字段是字符串类型的,传入一个整型的数据,也能够运行sql。 sql隐式转换的弊端 sql隐式转换&…...

Scratch021(画笔)

画笔模块 可以这么理解,画笔模块是Scratch的拓展模块,用它可以完成很多的功能,非常有趣! 案例要求 点击绿旗运行程序,页面显示需要绘制的背景。 可以使用鼠标移动画笔角色,按照顺序点击连线,…...

7.4.分块查找

一.分块查找的算法思想: 1.实例: 以上述图片的顺序表为例, 该顺序表的数据元素从整体来看是乱序的,但如果把这些数据元素分成一块一块的小区间, 第一个区间[0,1]索引上的数据元素都是小于等于10的, 第二…...

docker详细操作--未完待续

docker介绍 docker官网: Docker:加速容器应用程序开发 harbor官网:Harbor - Harbor 中文 使用docker加速器: Docker镜像极速下载服务 - 毫秒镜像 是什么 Docker 是一种开源的容器化平台,用于将应用程序及其依赖项(如库、运行时环…...

ssc377d修改flash分区大小

1、flash的分区默认分配16M、 / # df -h Filesystem Size Used Available Use% Mounted on /dev/root 1.9M 1.9M 0 100% / /dev/mtdblock4 3.0M...

爬虫基础学习day2

# 爬虫设计领域 工商:企查查、天眼查短视频:抖音、快手、西瓜 ---> 飞瓜电商:京东、淘宝、聚美优品、亚马逊 ---> 分析店铺经营决策标题、排名航空:抓取所有航空公司价格 ---> 去哪儿自媒体:采集自媒体数据进…...

RNN避坑指南:从数学推导到LSTM/GRU工业级部署实战流程

本文较长,建议点赞收藏,以免遗失。更多AI大模型应用开发学习视频及资料,尽在聚客AI学院。 本文全面剖析RNN核心原理,深入讲解梯度消失/爆炸问题,并通过LSTM/GRU结构实现解决方案,提供时间序列预测和文本生成…...

Rapidio门铃消息FIFO溢出机制

关于RapidIO门铃消息FIFO的溢出机制及其与中断抖动的关系,以下是深入解析: 门铃FIFO溢出的本质 在RapidIO系统中,门铃消息FIFO是硬件控制器内部的缓冲区,用于临时存储接收到的门铃消息(Doorbell Message)。…...

【7色560页】职场可视化逻辑图高级数据分析PPT模版

7种色调职场工作汇报PPT,橙蓝、黑红、红蓝、蓝橙灰、浅蓝、浅绿、深蓝七种色调模版 【7色560页】职场可视化逻辑图高级数据分析PPT模版:职场可视化逻辑图分析PPT模版https://pan.quark.cn/s/78aeabbd92d1...

智能AI电话机器人系统的识别能力现状与发展水平

一、引言 随着人工智能技术的飞速发展,AI电话机器人系统已经从简单的自动应答工具演变为具备复杂交互能力的智能助手。这类系统结合了语音识别、自然语言处理、情感计算和机器学习等多项前沿技术,在客户服务、营销推广、信息查询等领域发挥着越来越重要…...

VM虚拟机网络配置(ubuntu24桥接模式):配置静态IP

编辑-虚拟网络编辑器-更改设置 选择桥接模式,然后找到相应的网卡(可以查看自己本机的网络连接) windows连接的网络点击查看属性 编辑虚拟机设置更改网络配置,选择刚才配置的桥接模式 静态ip设置: 我用的ubuntu24桌…...

GruntJS-前端自动化任务运行器从入门到实战

Grunt 完全指南:从入门到实战 一、Grunt 是什么? Grunt是一个基于 Node.js 的前端自动化任务运行器,主要用于自动化执行项目开发中重复性高的任务,例如文件压缩、代码编译、语法检查、单元测试、文件合并等。通过配置简洁的任务…...