深入探究序列化与反序列化:原理、应用和最佳实践

news2024/11/20 17:38:14

目录

  • 什么是对象的序列化和反序列化
  • 序列化步骤
  • 反序列化步骤
  • 案例演示
  • Java中哪些字段不能序列化
  • 序列化与反序列化的重要性
  • 序列化与反序列化的应用场景

什么是对象的序列化和反序列化

序列化(Serialization)是指将对象转化为字节流的过程,以便于存储或通过网络进行传输。
反序列化(Deserialization)则是将字节流转化为对象的过程,恢复原始对象的状态。

在计算机科学中,序列化和反序列化是常用的数据处理技术,用于在不同系统、不同编程语言之间传递对象或持久化对象的状态。
在这里插入图片描述

序列化步骤

1.创建输出流:将对象写入到输出流中。
2.对象编码:将对象的数据转化为字节流的形式,可以使用不同的编码方式(如二进制编码、JSON、XML等)。
3.输出到目标:将编码后的字节流输出到目标位置,如文件、内存、网络等。

反序列化步骤

1.创建输入流:从输入流中读取字节流。
2.对象解码:将字节流解码为原始对象的数据形式。
3.构建对象:使用解码后的数据构建对象,并恢复对象的状态。

案例演示

在Java中,序列化和反序列化是通过实现Serializable接口来实现的。
要进行序列化,需要按以下步骤进行操作:
确保类实现了java.io.Serializable接口。
创建一个输出流(如java.io.FileOutputStream)将对象写入文件或网络流中。
创建一个java.io.ObjectOutputStream对象,将其连接到输出流上。
使用ObjectOutputStream的writeObject()方法将对象写入输出流。

示例代码如下所示:

public class SerializationExample {
    public static void main(String[] args) {
        MyClass obj = new MyClass(); // 要进行序列化的对象

        try {
            FileOutputStream fileOut = new FileOutputStream("data.ser"); // 序列化的目标文件
            ObjectOutputStream out = new ObjectOutputStream(fileOut);
            out.writeObject(obj); // 将对象写入输出流
            out.close();
            fileOut.close();
            System.out.println("对象已被序列化并保存为 data.ser");
        } catch(IOException e) {
            e.printStackTrace();
        }
    }
}

要进行反序列化,需要按照以下步骤操作:
1.创建一个输入流(如java.io.FileInputStream)读取序列化的对象。
2.创建一个java.io.ObjectInputStream对象,将其连接到输入流上。
3.使用ObjectInputStream的readObject()方法从输入流中读取对象,返回一个Object类型的对象。
将返回的对象转换为需要的类型(例如,强制类型转换为具体的类)。
示例代码如下所示:

public class DeserializationExample {
    public static void main(String[] args) {
        MyClass obj = null;
        
        try {
            FileInputStream fileIn = new FileInputStream("data.ser"); // 读取序列化的文件
            ObjectInputStream in = new ObjectInputStream(fileIn);
            obj = (MyClass) in.readObject(); // 从输入流中读取对象并转换类型
            in.close();
            fileIn.close();
        } catch(IOException e) {
            e.printStackTrace();
            return;
        } catch(ClassNotFoundException e) {
            e.printStackTrace();
            return;
        }
        
        System.out.println("对象已成功反序列化");
        // 对反序列化后的对象进行操作
        // ...
    }
}

Java中哪些字段不能序列化

在Java中,有一些字段是不能被序列化的。这些字段包括:

  • 静态变量(static variables):静态变量属于类级别,而不是实例级别。它们不包含在任何特定的对象中,因此不能被序列化。
  • transient变量(transient variables):使用transient关键字修饰的变量不会被序列化。transient变量通常用于表示临时状态或敏感信息,因此在序列化过程中会被忽略。
  • 方法(methods):在Java中,方法是不能被序列化的。只有对象的数据状态才能被序列化和反序列化。
  • 匿名内部类和局部内部类(anonymous inner classes and local inner classes):匿名内部类和局部内部类都包含对外部类的引用,这会导致序列化时的问题。
  • 类型为java.util.function包中的函数式接口类型。由于函数式接口通常具有lambda表达式或方法引用,因此它们无法被序列化。

需要注意的是,如果一个类实现了Serializable接口,但其中包含不可序列化的字段,则在序列化该类的实例时,这些字段的值将被忽略。如果需要对这些字段进行序列化,可以通过自定义序列化过程来实现。

为了避免某些字段被序列化,可以使用transient关键字修饰这些字段,让它们在序列化过程中被忽略。例如:

public class MyClass implements Serializable {
    private transient int transientField;  // transient字段,在序列化时被忽略

    // 其他字段和方法...
}

在使用transient关键字控制字段的序列化行为时,有几个方面需要注意:
序列化版本兼容性:当你对类进行修改时,特别是涉及到需要序列化的字段时,需要注意序列化版本的兼容性。如果对已序列化的对象进行反序列化时,版本不兼容可能会导致异常或数据丢失。建议在类中添加一个serialVersionUID字段,并在进行类的修改时适当更新它,以确保反序列化时的版本兼容性。

序列化与反序列化的重要性

  • 可实现跨平台和跨语言的数据交换,使得不同系统之间可以共享数据。
  • 可进行数据持久化,将对象保存到存储介质中,以便再次读取和使用。
  • 可用于远程调用,将对象通过网络传输到远程系统,并在远程系统上还原为对象进行处理。
  • 在不同的编程语言中,通常都会提供相应的序列化和反序列化机制或库,以便开发者方便地实现对象的序列化和反序列化操作。

序列化与反序列化的应用场景

  • 敏感数据的安全控制:在使用transient关键字标记字段时,请确保其中不包含敏感信息,例如密码、密钥等。被transient修饰的字段在对象被序列化后将被忽略,这样可以避免敏感数据泄露。
  • 自定义序列化逻辑:某些情况下,你可能需要自定义对象的序列化和反序列化逻辑。可以通过实现writeObject()和readObject()方法来实现自定义的序列化过程。在这种情况下,即使字段被transient修饰,你也可以在这些方法中手动控制字段的序列化行为。
  • 跨平台兼容性:如果你的应用程序需要在不同的平台上运行或与其他语言进行交互,务必注意跨平台兼容性问题。某些平台或语言可能对transient关键字的处理方式有所不同,因此在进行跨平台或跨语言的序列化操作时需要格外小心。

总之,在使用transient关键字时,要仔细考虑对象的序列化行为以及对应的框架的特性。确保版本兼容性、安全控制和跨平台兼容性,以确保序列化操作的正确性和稳定性。

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

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

相关文章

点燃创意,发掘绘图潜能——FireAlpaca for Mac专业绘图软件

无论您是一位艺术家、插画师还是爱好绘图的人,寻找一款功能强大且易于使用的绘图软件都是必不可少的。而FireAlpaca for Mac作为一款专为Mac用户设计的专业绘图软件,将点燃您的创意,帮助您发掘绘图的潜能。 FireAlpaca for Mac拥有丰富的工具…

Linux,计算机网络,数据库

Linux,计算机网络,数据库,操作系统 一、Linux1、linux查看进程2、linux基本命令3、top命令、查看磁盘 二、计算机网络1、HTTP的报文段请求 Repuest响应 Response 2、HTTP用的什么连接3、TCP的三次握手与四次挥手三次握手四次挥手 4、在浏览器…

【RabbitMQ实战】02 生产者和消费者示例

在上一节中,我们使用docker部署了RabbitMQ,这一节我们将写一段生产者和消费者的代码。将用到rabbitmq的原生API来进行生产和发送消息。 一、准备工作 开始前,我们先在RabbitMQ控制台建相好关的数据 本机的RabbitMQ部署机器是192.168.56.201…

竞赛 基于深度学习的动物识别 - 卷积神经网络 机器视觉 图像识别

文章目录 0 前言1 背景2 算法原理2.1 动物识别方法概况2.2 常用的网络模型2.2.1 B-CNN2.2.2 SSD 3 SSD动物目标检测流程4 实现效果5 部分相关代码5.1 数据预处理5.2 构建卷积神经网络5.3 tensorflow计算图可视化5.4 网络模型训练5.5 对猫狗图像进行2分类 6 最后 0 前言 &#…

【操作系统笔记五】内存布局内存映射

虚拟内存布局 虚拟地址空间大小: 32位虚拟地址空间 [0 ~ 2^32 - 1] 总共4GB64位虚拟地址空间 [0 ~ 2^64 - 1] 总共16 777 216TB 不管是运行在用户态还是内核态,都需要使用虚拟地址,这是因为计算机硬件要求的,CPU要经过地址转换得…

观测云产品更新 | 优化日志数据转发、索引绑定、基础设施自定义等

观测云更新 日志 数据转发:新增外部存储转发规则数据查询;支持启用/禁用转发规则;绑定索引:日志易新增标签绑定,从而实现更细颗粒度的数据范围查询授权能力。 基础设施 > 自定义 【默认属性】这一概念更改为【必…

绝佳盘点:2023年最好用的AI机器人

近几年人工智能可以说是以前所未有的速度在发展,越来越多的企业意识到,在运营的过程中学会熟练地应用AI机器人是可以帮助他们很好地提高工作效率的。那么有哪些AI机器人比较好用呢?接下来我会介绍几个个人觉得比较优秀的AI机器人工具&#xf…

【51单片机】6-点亮第一个LED灯

1.单片机编程的一般步骤 1.目标分析 点亮开发板上的LED灯 2.原理图【电路图】分析 1.目标器件(LED)工作原理 2.相关模块电路连接 3.控制线路分析:相关IO端口是哪些? 3.代码编写,编译 4.下载于调试 2.原理图与控制…

杂记 | 使用gitlab-runner将python项目以docker镜像方式流水线部署到服务器(解决部署缓慢和时区不对的问题)

文章目录 01 需求背景1.1 需求1.2 步骤 02 编写BaseDockerfile2.1 编写2.2 说明2.3 执行 03 编写Dockerfile04 编写.gitlab-ci.yml05 项目结构 01 需求背景 1.1 需求 我有一个python项目,该项目可能是一个服务器监控程序,也可能是一个后端程序&#xf…

【开关稳压器】LMR16030SDDA、LMR38010FDDAR,汽车类LMR43610MSC5RPERQ1低 EMI 同步降压稳压器

一、LMR16030SDDA 开关稳压器 IC REG BUCK ADJ 3A 8SOPWR LMR16030 是一款带有集成型高侧 MOSFET 的 60V、3A SIMPLE SWITCHER 降压稳压器。该器件具有4.3V 至 60V 的宽输入范围,适用于从工业到汽车各类应用中非稳压电源的电源调节。该稳压器在睡眠模式下的静态电流…

基于TensorFlow+CNN+协同过滤算法的智能电影推荐系统——深度学习算法应用(含微信小程序、ipynb工程源码)+MovieLens数据集(二)

目录 前言总体设计系统整体结构图系统流程图 运行环境模块实现1. 模型训练1)数据集分析2)数据预处理 相关其它博客工程源代码下载其它资料下载 前言 本项目专注于MovieLens数据集,并采用TensorFlow中的2D文本卷积网络模型。它结合了协同过滤…

h5下载文件,无兼容问题~

最近写了个页面,打开页面出现文件列表,用户可以下载文件。 失败方案 使用a标签进行下载,参考代码如下: 因为有批量下载的需求,这里将xhr请求单独封装到downloadFile.js中 // downloadFile.js const downloadFile …

Flutter超好用的路由库-fluro

文章目录 fluro的介绍fluro简介安装和导入路由配置导航到路由参数传递 fluro的典型使用创建路由管理类代码解释例子小结 初始化路由导航到路由 总结 fluro的介绍 fluro简介 fluro是一个流行的Flutter插件,用于实现高级路由管理。它提供了灵活的路由配置和导航功能…

VR科普研学基地科普开放日普乐蛙VR体验馆沉浸式体验设备

广州科普开放日来啦 2023年9月广州科普开放日来啦,9月16日周六上午9点,广州卓远非常荣幸地迎来了一批前来体验的家庭。 比原定的集合时间提前了近1个小时,已经开始有家长带着小朋友来到了VR科普基地,可见大家对VR科普体验的热情和…

轻量服务器是不是vps ?和vps有什么区别

​  轻量型服务器是介于云服务器和共享型服务器之间的一种解决方案。它提供较为独立的资源分配,但规模较小,适用于中小型网站和应用程序。轻量型服务器的硬件资源来源于大型的公有云集群的虚拟化技术。轻量型服务器的性能和带宽可能会稍逊于云服务器。…

【笨~~~】在python中导入另一个模块的函数时,为什么会运行模块中剩下的部分??顶层?

一个程序员一生中可能会邂逅各种各样的算法,但总有那么几种,是作为一个程序员一定会遇见且大概率需要掌握的算法。今天就来聊聊这些十分重要的“必抓!”算法吧~ Python导入了其他文件中的函数,运行时连着这个文件一起运行了 在py…

椭圆曲线加密算法

椭圆曲线密码学(Elliptic curve cryptography),简称ECC,是一种建立公开密钥加密的算法,也就是非对称加密。类似的还有RSA,ElGamal算法等。ECC被公认为在给定密钥长度下最安全的加密算法。比特币中的公私钥生…

什么是文档签名证书?PDF文档怎么签名?

什么是文档签名证书?在“互联网”时代,电子合同、电子证照、电子病历、电子保单等各类电子文档无纸化应用成为常态。如何让电子文档的签署、审批具有公信力及法律效力,防止伪造签名、假冒签名等问题出现,是电子文档无纸化应用的主…

画一个时钟(html+css+js)

这是一个很简约的时钟。。。。。。。 效果&#xff1a; 代码&#xff1a; <template><div class"demo-box"><div class"clock"><ul class"mark"><liv-for"(rotate, index) in rotatedAngles":key"i…

echarts图表 实现高度按照 内容撑起来或者超出部分滚动展示效果

背景&#xff1a;因为数据不固定 高度写死导致数据显示不全&#xff0c;所以图表高度要根据内容计算 实现代码如下&#xff1a; <divv-if"showCharts"id"business-bars"class"chart":style"{ height: chartHeight px }"></d…