Java 序列化详解

2023-10-28

Java 序列化(Serialization)是指将一个 Java 对象转换成字节序列,以便在网络上传输或存储在本地磁盘中。而反序列化(Deserialization)则是将已经序列化的字节序列恢复为 Java 对象。Java 提供了自带的序列化机制,可以通过实现 Serializable 接口以及使用 ObjectOutputStream 和 ObjectInputStream 类来实现序列化和反序列化。

1. 序列化的基本概念和使用方法

1.1 基本概念

Java 序列化的基本概念包括以下几个方面:

  • 序列化:将一个对象转换为二进制数据流,方便进行网络传输、磁盘存储等操作。
  • 反序列化:将序列化后的二进制数据流还原成原来的对象,重新获取对象的引用。
  • Serializable 接口:Java 提供的标记接口,用于标识一个类可以被序列化。
  • serialVersionUID:用于识别版本之间的兼容性,防止序列化和反序列化的版本不一致导致出错。
  • transient 关键字:标记一个字段不需要进行序列化。

1.2 使用方法

Java 序列化的使用方法如下:

  1. 定义一个需要序列化的类,并实现 Serializable 接口:
public class User implements Serializable {
    private static final long serialVersionUID = 1L;
    
    private String name;
    private int age;
    
    // getters and setters
}
  1. 创建一个 ObjectOutputStream 对象,并将需要序列化的对象写入到输出流中:
User user = new User();
user.setName("Tom");
user.setAge(18);

ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("user.ser"));
oos.writeObject(user);
oos.close();
  1. 创建一个 ObjectInputStream 对象,并从输入流中读取序列化后的对象:
ObjectInputStream ois = new ObjectInputStream(new FileInputStream("user.ser"));
User user = (User) ois.readObject();
ois.close();

2. 序列化的实现原理和注意事项

2.1 实现原理

Java 序列化的实现原理可以简单地概括为:将对象的状态以二进制格式保存在文件中,以便在需要时恢复该对象的状态。

在具体实现中,Java 序列化包括以下几个步骤:

  1. 创建一个 ObjectOutputStream 对象,用于将对象写入输出流中。
  2. ObjectOutputStream 对象首先会检查对象是否为 null,如果是 null,则会直接写入一个 null 标记。
  3. ObjectOutputStream 对象会获取对象的类信息,并将其写入输出流中。
  4. ObjectOutputStream 对象会根据对象的类信息,获取对象的每个字段,并将其写入输出流中,如果某个字段被标记为 transient,则不进行序列化。对于包含其他对象的字段,递归执行序列化操作。
  5. ObjectOutputStream 对象在写入对象的所有字段之后,会写入一个结束标记。

2.2 注意事项

在 Java 序列化过程中,有以下几个注意事项:

  1. 需要序列化的类必须实现 Serializable 接口。
  2. serialVersionUID 用于判断序列化和反序列化的版本是否一致,建议长期保存。
  3. transient 关键字用于标识一个字段不需要进行序列化。
  4. 序列化操作是有代价的,如果需要频繁地进行序列化操作,需要考虑到性能问题。
  5. 序列化后的文件可以在网络中传输,但需要注意安全问题。

3. 反序列化的基本概念和使用方法

3.1 基本概念

Java 反序列化的基本概念包括以下几个方面:

  • 反序列化:将序列化后的二进制数据流还原成原来的对象,重新获取对象的引用。
  • ObjectInputStream 类:用于从输入流中读取序列化后的对象。
  • readObject() 方法:用于从输入流中读取序列化后的对象,返回 Object 类型的对象。

3.2 使用方法

Java 反序列化的使用方法如下:

  1. 创建一个 ObjectInputStream 对象,并从输入流中读取序列化后的对象:
ObjectInputStream ois = new ObjectInputStream(new FileInputStream("user.ser"));
User user = (User) ois.readObject();
ois.close();

4. 反序列化中的安全问题以及如何避免

4.1 安全问题

Java 序列化和反序列化在网络传输等场景中广泛使用,但同时也存在一些安全问题。例如,Java 序列化在反序列化时会自动执行对象中的构造函数,从而可能导致安全漏洞。攻击者可以通过构造恶意数据,使得反序列化操作执行他们所期望的恶意情况,从而实现攻击目的。

比较常见的攻击类型包括:

  • 远程执行代码(Remote Code Execution,RCE):使用序列化和反序列化机制,向另一个 Java 程序发送一个“恶意”对象,使得对方程序以攻击者的意愿执行代码。
  • 反序列化注入(Deserialization Injection):攻击者通过在序列化文件中插入特定的序列化对象来引发反序列化操作,并实现对目标应用系统的攻击。

4.2 避免安全问题

避免 Java 序列化和反序列化中的安全问题可以采取以下一些措施:

  1. 不要信任远程传输的数据:在反序列化前,应该验证序列化数据的源头,确保其来源可靠。
  2. 使用白名单来限制反序列化的类:在反序列化时使用白名单来限制可反序列化的类,只允许反序列化特定的类。
  3. 尽量避免序列化敏感数据:尽量避免将敏感数据序列化到文件或网络中,而是采用加密等方式来保护数据的安全性。
  4. 升级 JDK 版本:从 JDK8 开始,Java 系统已经默认禁止使用无效的 serialVersionUID 来验证序列化版本号,而是自动生成一个新的 serialVersionUID。

综上所述,Java 序列化和反序列化是 Java 编程中重要的一个部分,在需要进行对象的跨进程、跨网络传输等场景中,会带来很大的便利。但是在使用过程中,需要注意安全问题,并对可能的安全漏洞进行防范。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Java 序列化详解 的相关文章

  • 在 Java 中连接和使用 Cassandra

    我已经阅读了一些关于 Cassandra 是什么以及它可以做什么的教程 但我的问题是如何在 Java 中与 Cassandra 交互 教程会很好 如果可能的话 有人可以告诉我是否应该使用 Thrift 还是 Hector 哪一个更好以及为什
  • 如何为最终用户方便地启动Java GUI程序

    用户想要从以下位置启动 Java GUI 应用程序Windows 以及一些额外的 JVM 参数 例如 javaw Djava util logging config file logging properties jar MyGUI jar
  • Java Swing:从 JOptionPane 获取文本值

    我想创建一个用于 POS 系统的新窗口 用户输入的是客户拥有的金额 并且窗口必须显示兑换金额 我是新来的JOptionPane功能 我一直在使用JAVAFX并且它是不同的 这是我的代码 public static void main Str
  • 为什么 i++ 不是原子的?

    Why is i Java 中不是原子的 为了更深入地了解 Java 我尝试计算线程中循环的执行频率 所以我用了一个 private static int total 0 在主课中 我有两个线程 主题 1 打印System out prin
  • Java JDBC:更改表

    我希望对此表进行以下修改 添加 状态列 varchar 20 日期列 时间戳 我不确定该怎么做 String createTable Create table aircraft aircraftNumber int airLineCompa
  • INSERT..RETURNING 在 JOOQ 中不起作用

    我有一个 MariaDB 数据库 我正在尝试在表中插入一行users 它有一个生成的id我想在插入后得到它 我见过this http www jooq org doc 3 8 manual sql building sql statemen
  • 路径中 File.separator 和斜杠之间的区别

    使用有什么区别File separator和一个正常的 在 Java 路径字符串中 与双反斜杠相反 平台独立性似乎不是原因 因为两个版本都可以在 Windows 和 Unix 下运行 public class SlashTest Test
  • Mockito when().thenReturn 不必要地调用该方法

    我正在研究继承的代码 我编写了一个应该捕获 NullPointerException 的测试 因为它试图从 null 对象调用方法 Test expected NullPointerException class public void c
  • 十进制到八进制的转换[重复]

    这个问题在这里已经有答案了 可能的重复 十进制转换错误 https stackoverflow com questions 13142977 decimal conversion error 我正在为一个类编写一个程序 并且在计算如何将八进
  • 禁止的软件包名称:java

    我尝试从数据库名称为 jaane 用户名 Hello 和密码 hello 获取数据 错误 java lang SecurityException Prohibited package name java at java lang Class
  • 如何将 pfx 文件转换为 jks,然后通过使用 wsdl 生成的类来使用它来签署传出的肥皂请求

    我正在寻找一个代码示例 该示例演示如何使用 PFX 证书通过 SSL 访问安全 Web 服务 我有证书及其密码 我首先使用下面提到的命令创建一个 KeyStore 实例 keytool importkeystore destkeystore
  • 总是使用 Final?

    我读过 将某些东西做成最终的 然后在循环中使用它会带来更好的性能 但这对一切都有好处吗 我有很多地方没有循环 但我将 Final 添加到局部变量中 它会使速度变慢还是仍然很好 还有一些地方我有一个全局变量final 例如android Pa
  • 加密 JBoss 配置中的敏感信息

    JBoss 中的标准数据源配置要求数据库用户的用户名和密码位于 xxx ds xml 文件中 如果我将数据源定义为 c3p0 mbean 我会遇到同样的问题 是否有标准方法来加密用户和密码 保存密钥的好地方是什么 这当然也与 tomcat
  • AWS 无法从 START_OBJECT 中反序列化 java.lang.String 实例

    我创建了一个 Lambda 函数 我想在 API 网关的帮助下通过 URL 访问它 我已经把一切都设置好了 我还创建了一个application jsonAPI Gateway 中的正文映射模板如下所示 input input params
  • Eclipse Java 远程调试器通过 VPN 速度极慢

    我有时被迫离开办公室工作 这意味着我需要通过 VPN 进入我的实验室 我注意到在这种情况下使用 Eclipse 进行远程调试速度非常慢 速度慢到调试器需要 5 7 分钟才能连接到远程 jvm 连接后 每次单步执行断点 行可能需要 20 30
  • 仅将 char[] 的一部分复制到 String 中

    我有一个数组 char ch 我的问题如下 如何将 ch 2 到 ch 7 的值合并到字符串中 我想在不循环 char 数组的情况下实现这一点 有什么建议么 感谢您花时间回答我的问题 Use new String value offset
  • 如何从指定日期获取上周五的日期? [复制]

    这个问题在这里已经有答案了 如何找出上一个 上一个 星期五 或指定日期的任何其他日期的日期 public getDateOnDay Date date String dayName 我不会给出答案 先自己尝试一下 但是 也许这些提示可以帮助
  • 在mockito中使用when进行模拟ContextLoader.getCurrentWebApplicationContext()调用。我该怎么做?

    我试图在使用 mockito 时模拟 ContextLoader getCurrentWebApplicationContext 调用 但它无法模拟 here is my source code Mock org springframewo
  • 声明的包“”与预期的包不匹配

    我可以编译并运行我的代码 但 VSCode 中始终显示错误 早些时候有一个弹出窗口 我不记得是什么了 我点击了 全局应用 从那以后一直是这样 Output is there but so is the error The declared
  • 使用 JMF 创建 RTP 流时出现问题

    我正处于一个项目的早期阶段 需要使用 RTP 广播DataStream创建自MediaLocation 我正在遵循一些示例代码 该代码目前在rptManager initalize localAddress 出现错误 无法打开本地数据端口

随机推荐

  • 换行CRLF,LF和CR,IntelliJ下设置默认为LF

    在window下开发有一个大坑 就是换行默认是CRLF 但是Linux下只有换行LF 这样代码提交后 会出现编译问题 首先我们先介绍CRLF LF和CR CR是MAC老版本的做法 就是回车 但是后来的MAC系统统一换成LF了 LF是Linu
  • python计算圆周率

    最近一段时间在学习python算法 今天分享5种python计算圆周率的方法 1 割圆法 2 无穷级数法 3 蒙特卡洛法 4 梅钦法 5 拉马努金法 题目来自头歌习题 希望能帮到大家 代码如下 1 割圆法 编程实现割圆法计算圆周率 并输出分
  • excel打开后灰色不显示内容_如何解决EXCEL表格打开显示空白(灰色)的问题

    Excel表格打开没有工作表信息 显示空白 界面是灰色的 大多是单一表格有这种现象 其他表格没有问题 一般是Excel设置问题 方案一 打开故障Excel 视图 窗口 取消隐藏 方案二 在系统左下角开始菜单 找到所有程序 Microsoft
  • es 指定排序字段_ElasticSearch按照指定字段排序

    默认情况下 ES的结果集会按照相关性进行排序 相关性越高 排名越靠前 不过这个规则到了实际应用中往往并不能完全满足我们多变的需求 对于查询结果 除了要找出它们来 还经常需要根据某一规则进行排列 这个规则一般就是指按照某一特定字段排序 按照d
  • Cas5.3服务器集成DM8 达梦数据库

    DM8达梦数据库相关准备 1 安装DM8达梦数据库并安装相关数据库实例 省略一千字 2 新建ucas auth user表 并增加相关用户条记录 DROP TABLE IF EXISTS ucas auth user CREATE TABL
  • 命令行修改java 内存,在命令行上增加jMeter的内存

    I am running jMeter from the command line on a Mac Today it threw an Out of memory heap space error newbie sh jmeter sh
  • PlayerPawn(鼠标控制移动、旋转、大小缩放)

    ue4制作PlayerPawn 鼠标拖动 旋转 YLimtMin 值 89 YLimtMax 值 10 鼠标滚轮键 控制弹簧臂长短 主要控制移动开关 函数LimtMovsePicth
  • STL——map、set等红黑树结构的最后一个元素

    map set等背后由于红黑树的关系 插入元素后便成为 平衡 搜索树了 所以末尾元素默认为最大值 得到该值的方法 1 利用 rbegin 反向迭代器 int main int argc char argv map
  • IntersectionObserver实现小程序长列表优化

    IntersectionObserver实现小程序长列表优化 关于 IntersectionObserver 思路 这里以一屏数据为单位 一个分页的10条数据 最好大于视口高度 监听每一屏数据和视口的相交比例 即用户能不能看到它 只将可视范
  • 接口测试之Jmeter+Ant+Jenkins接口自动化测试平台

    平台简介 一个完整的接口自动化测试平台需要支持接口的自动执行 自动生成测试报告 以及持续集成 Jmeter支持接口的测试 Ant支持自动构建 而Jenkins支持持续集成 所以三者组合在一起可以构成一个功能完善的接口自动化测试平台 环境准备
  • IDEA中输入法无法输入中文

    偶尔而遇到这个问题 又忘记了 记录下 在idea内无法输入中文 win环境可以 很简单快捷键 ctrl shift e 解决问题 看到好多文章去改变量 改配置文件 这
  • LinearLayout加载动态view时显示不全解决办法

    问题 在某个主要Layout里面有个LinearLayout 用来动态加载别的view页面 如果需要加载的动态view内容很空洞 例如没有足够的Text长度来撑起整个layout宽度 这时候这个被加载的view就会不能以fill paren
  • 图像处理入门5-特征提取

    特征提取 图像特征提取属于图像分析的范畴 是对图像信息的深层理解 是数字图像处理的高级阶段 同时也是图像识别的开始 特征工程是图像处理的必备工具 所以掌握它的重要性不言而喻 什么是特征 特征是某一类对象区别于其他类对象的相应 本质 特点或特
  • mybatis-plus的落地实践

    一 mybatis plus官网 MyBatis Plus 二 应用层面 mapper entitty 三 配置 1 引入依赖
  • cv_bridge 冲突(完美解决)

    ubuntu18 04 ros 用 opencv3 2 0 版本 设置 cmake 找到 OpenCVConfig cmake CMakeLists txt 文件里 find package 之前加一行 set set OpenCV DIR
  • 2018.07.20 WorkSummary——04

    今天任务 优化后台代码 简化前端js部分 收获 1 数据库部分表关联与左右连接的分别占用内存的问题 一下面的为例子 SELECT FROM 表a left joint 表b ON 表a bid 表b id LEFT JOIN 表c ON 表
  • 现代控制理论5——稳定性与稳定性判据

    注 本文是在MOOC平台上学习西北工业大学 现代控制理论基础 郭建国 赵斌 郭宗易 的课程进行随笔记录与整理 一 李雅普诺夫稳定性理论 1 前期铺垫 稳定性是系统正常工作的重要特性 稳定性 是描述初始条件 不一定为0 下 系统是否具有收敛性
  • vue实用插件分享

  • 特征学习与特征工程

    特征学习与特征工程 表示学习 当我们学习一个复杂概念时 总想有一条捷径可以化繁为简 机器学习模型也不例外 如果有经过提炼的对于原始数据的更好表达 往往可以使得后续任务事倍功半 这也是表示学习的基本思路 即找到对于原始数据更好的表达 以方便后
  • Java 序列化详解

    Java 序列化 Serialization 是指将一个 Java 对象转换成字节序列 以便在网络上传输或存储在本地磁盘中 而反序列化 Deserialization 则是将已经序列化的字节序列恢复为 Java 对象 Java 提供了自带的