如何使用Externalizable接口自定义Java中的序列化
Java序列化过程的缺点
我们都知道如何使用Serializable接口序列化/反序列化一个对象,并且如何使用writeObject
和readObject方法自定义序列化过程。
但是这些自定义还不够,因为JVM可以完全控制序列化过程,而这些自定义逻辑只是默认序列化过程的补充。我们仍然必须通过调用ObjectOutputStream.defaultWriteObject()和ObjectInputStream.defaultReadObject()from writeObject和readObject方法使用默认的序列化逻辑。如果我们不调用这些默认方法,我们的对象将不会被序列化/反序列化。
默认序列化过程是完全递归的。因此,每当我们尝试序列化一个对象时,序列化过程会尝试使用我们的类(除了static和transient字段)序列化所有字段(原语和引用),这使得序列化过程非常缓慢。
现在,假设我们有一个包含许多字段的对象,由于某种原因我们不想序列化(这些字段将始终分配默认值)。使用默认的序列化过程,我们必须使所有这些字段都是瞬态的,但它仍然不会有效,因为会进行大量检查以查看字段是否是瞬态的。
正如我们所看到的,使用默认序列化过程有许多缺点,例如:
1.序列化的自定义是不够的,因为JVM可以完全控制序列化过程,而我们的自定义逻辑只是默认序列化过程的补充。
2.默认序列化过程是完全递归和缓慢的。
3.为了不对字段进行序列化,我们必须将其声明为瞬态,并且许多瞬态字段将再次使该过程变慢。
4.我们无法控制字段的序列化和反序列化方式。默认序列化过程在创建对象时不会调用构造函数,因此它无法调用构造函数提供的初始化逻辑。
什么是外化和可外化接口?
如上所述,默认的Java序列化效率不高。我们可以通过使用Externalizable接口而不是Serializable接口来解决其中的一些问题。
我们可以通过实现写自己的序列化逻辑外部化的界面和重写它的方法writeExternal()和readExternal()。但是使用这种方法,我们不会从JVM获得任何类型的默认序列化逻辑,我们需要提供完整的序列化和反序列化逻辑。
因此,非常有必要仔细编码和测试这些方法,因为它可能会破坏序列化过程。但是,如果正确实施,外部化过程与默认序列化过程相比非常快。
我们将使用下面的Employee类对象作为解释的示例:
序列化如何与Externalizable接口一起使用
正如我们上面看到的,在我们的例子Employee类,我们可以通过实现写自己的序列化逻辑外部化的界面和重写它的方法writeExternal()和readExternal()。
该对象可writeExternal通过调用DataOutput其原始值的writeObject 方法 或调用 ObjectOutput 对象,字符串和数组的方法来实现 保存其内容的方法 。
该对象可以readExternal通过调用DataInput基本类型的方法以及 readObject 对象,字符串和数组来实现 恢复其内容的方法 。该 readExternal方法必须以相同的顺序读取值,并使用与写入的相同类型 writeExternal。
要将对象序列化和反序列化为文件,我们需要按照Serializable示例中的相同步骤进行操作,这意味着调用ObjectOutputStream.writeObject()并ObjectInputStream.readObject()在以下代码中完成:
该Externalizable接口的子接口Serializable即Externalizable extends Serializable。因此,如果我们实现Externalizable接口并覆盖它writeExternal()和readExternal()方法,那么我们首先要优先考虑这些方法,而不是JVM提供的默认序列化机制。这些方法取代了自定义的实现writeObject和readObject方法。所以,如果我们还提供writeObject()和readObject(),那么他们将被忽略。
在序列化过程中,对每个要序列化的对象进行Externalizable 接口测试 。如果对象支持 Externalizable,writeExternal 则调用该 方法。如果对象不支持 Externalizable 并且实现
Serializable,则使用保存对象 ObjectOutputStream。
当一个 Externalizable 对象被重建,则使用公共无参数的构造创建的实例; 然后readExternal 调用该 方法。 Serializable通过从中读取对象来恢复它们 ObjectInputStream。
当一个 Externizable 对象被重建,通过使用公共的无参数构造的前创建的对象 readExternal 被调用的方法。如果不存在公共no-arg构造函数,则InvalidClassException 在运行时抛出a 。
使用 Externalizable,我们甚至可以序列化/反序列化瞬态变量,因此声明瞬态变为不必要。3.使用 Externalizable,如果需要,我们甚至可以序列化/反序列化静态变量。
一个 Externalizable实例可以通过指定一个替代对象 writeReplace 和 readResolve 在形成文件的方法 Serializable 接口。
Java 序列化也可用于深度克隆对象。Java克隆是Java社区中最值得商榷的主题,它确实有它的缺点,但它仍然是创建对象副本的最流行和最简单的方法,直到该对象完全填充Java克隆的强制条件。
有关于JAVA的问题可私信我交流!
如何使用Externalizable接口自定义Java中的序列化的更多相关文章
- Java中如何序列化一个对象(转)
转自:http://blog.csdn.net/chx10051413/article/details/40784667 http://www.cnblogs.com/baoendemao/p/380 ...
- Java中的序列化Serialable
Java中的序列化Serialable https://blog.csdn.net/caomiao2006/article/details/51588838
- Java中实现序列化的两种方式 Serializable 接口和 Externalizable接口
对象的序列化就是将对象写入输出流中. 反序列化就是从输入流中将对象读取出来. 用来实现序列化的类都在java.io包中,我们常用的类或接口有: ObjectOutputStream:提供序列化对象并把 ...
- 并发王者课-铂金1:探本溯源-为何说Lock接口是Java中锁的基础
欢迎来到<并发王者课>,本文是该系列文章中的第14篇. 在黄金系列中,我们介绍了并发中一些问题,比如死锁.活锁.线程饥饿等问题.在并发编程中,这些问题无疑都是需要解决的.所以,在铂金系列文 ...
- K:java中的序列化与反序列化
Java序列化与反序列化是什么?为什么需要序列化与反序列化?如何实现Java序列化与反序列化?以下内容将围绕这些问题进行展开讨论. Java序列化与反序列化 简单来说Java序列化是指把Java对象转 ...
- 在Java中进行序列化和反序列化
对象序列化的目标是将对象保存在磁盘中,或者允许在网络中直接传输对象. 对象序列化允许把内存中的Java对象转换成平台无关的二进制流,从而允许把这种二进制流持久保存在磁盘上或者通过网络将这种二进制流传输 ...
- java中的序列化问题
序列化就是一种用来处理对象流的机制,所谓对象流也就是将对象的内容进行流化,将数据分解成字节流,以便存储在文件中或在网络上传输.可以对流化后的对象进行读写操作,也可将流化后的对象传输于网络之间.序列化是 ...
- Java中的序列化与反序列化
序列化定义 将对象转换为字节流保存起来,并在以后还原这个对象,这种机制叫做对象序列化. 将一个对象保存到永久存储设备上称为持久化. 一个对象要想能够实现序列化,必须实现java.io.Serializ ...
- java中的序列化和反序列化
package cn.zhou; import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.Fil ...
随机推荐
- BMP 图像信息隐藏及检测
原理简介 针对文件结构的信息隐藏方法需详细掌握文件的格式,利用文件结构块之间的关系或根据块数据和块大小之间的关系来隐藏信息. BMP(Bitmap-File)图形文件是 Windows 采用的常见图形 ...
- nodejs实现聊天机器人
技术栈 服务端: koa.koa-route.koa-websocket.request. 客户端: html.css.js.websocket. 远程聊天API: http://api.qingyu ...
- Linux环境下进行分布式压测踩过的坑
背景:公司为了满足大并发的情况,需要测试组配合,就需要分布式压测,这里我把我踩过坑都记录下来: 环境:Linux + jmeter-v.5.1.1;使用3台2核4G的压力机: Q1: Server f ...
- 初识数据库(MySql)
一.简介 1.MySql是关系型数据库. 2.是一种开放源码软件, 3.是一种关联数据库管理系统. 4.服务器工作于客户端/服务端模式之下,或者是嵌入系统中. 数据库管理软件分类: 分两大类: 关系型 ...
- maven的pom.xml详解
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/20 ...
- spring中使用aop配置事务
spring的事务配置有5种方式,这里记录其中的一种:基于tx/aop声明式事务配置 在之前spring aop介绍和示例这篇所附代码的基础上进行测试 一.添加save方法 1.在testDao类里添 ...
- 百度脑图-离线版(支持Linux、Mac、Win)
免费好用的思维导图软件(在线版) 离线版:桌面版脑图是基于百度脑图的本地化版本,帮助你在没有互联网环境的情况下,依然可以使用脑图工具. 百度脑图帮助你进行思维导图,可以运用于学习.写作.沟通.演讲.管 ...
- Spring事务传播行为中可能的坑点
一.简介 Spring事务配置及相关说明详见:https://www.cnblogs.com/eric-fang/p/11052304.html.这里说明spring事务的几点注意: 1.默认只会检查 ...
- 关于webpack
webpack 是一个模块打包器,能够把所有的文件都当做是一个模块 它把所有的文件资源(js,json,css,sass,图片)都看作为模块 将这些文件资源解析处理以后,生成对应的打包文件 使用web ...
- SpringBootSecurity学习(03)网页版登录添加自定义登录页面
自定义登录页面 前面无论是使用默认配置,还是自定义配置类,都是使用的springboot-security自带的登录页面,自带的登录页面在这个版本虽然设计的非常不错,但是在实际开发中,我们通常还是使用 ...