如何使用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 ...
随机推荐
- java中存储机制堆栈。
一.java的六种存储地址及解释 1) 寄存器(register):这是最快的存储区,因为它位于不同于其他存储区的地方——处理器内部.但是寄存器的数量极其有限,所以寄存器由编译器根据需求进行分配.你不 ...
- javascript 中 typeof 和 instanceof 的区别
在 javascript 中经常会用到 typeof 和 instanceof 来判断一个对象的类型,可能 typeof 用得多些,那来看看这两个之间的区别吧. typeof : typeof 是一个 ...
- yum rpm apt-get wget 辨析
1)wget: 类似于迅雷,是一种下载工具,通过HTTP.HTTPS.FTP三个最常见的TCP/IP协议下载,并可以使用HTTP代理名字是World Wide Web”与“get”的结合.类似于cur ...
- ELKBR部署检测项目日志
ELK filebeat:具有日志收集功能,相比logstash,+filebeat更轻量,占用资源更少,适合客户端使用. redis消息队列选型:Redis 服务器通常都是用作 NoSQL 数据库, ...
- android View的测量和绘制
本篇内容来源于android 群英传(徐易生著) 我写到这里,是觉得徐易生讲的确实很好, 另外加入了一些自己的理解,便于自己基础的提高. 另外参考:http://www.gcssloop.com/cu ...
- SSM相关面试题(简答)
1.springmvc的执行 流程: 2.mybstis的执行流程: 3.ioc和DI的理解: 4.对aop的理解: 5.spring中常见的设计模式: 6.spring中声明式事务处理的配置: ...
- ACM讲课之字符串
本次讲课讲全面介绍字符串以及如何使用字符串解决具体问题. 一.什么是字符串 1.如何存储字符串 平时我们使用的变量有很多,int代表整型变量,double代表浮点型变量,char代表字符型变量,那么对 ...
- java需要了解和学习的技能
一:系统架构师是一个最终确认和评估系统需求,给出开发规范,搭建系统实现的核心构架,并澄清技术细节.扫清主要难点的技术人员.主要着眼于系统的“技术实现”.因此他/她应该是特定的开发平台.语言.工具的大师 ...
- 【C/C++】qsort函数的使用方法和细节
函数概述 qsort 为quick_sort的简写,意为快速排序,主要用于对各种数组的排序. 因为数组的元素可能是任何类型的,甚至是结构或者联合,所以必须高数函数qsort如何确定两个数组元素哪一个& ...
- Recovery启动流程--recovery.cpp分析
这篇文章主要通过分析高通recovery目录下的recovery.cpp源码,对recovery启动流程有一个宏观的了解. 当开机以后,在lk阶段,如果是recovery,会设置boot_into_r ...