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中的序列化的更多相关文章

  1. Java中如何序列化一个对象(转)

    转自:http://blog.csdn.net/chx10051413/article/details/40784667 http://www.cnblogs.com/baoendemao/p/380 ...

  2. Java中的序列化Serialable

    Java中的序列化Serialable https://blog.csdn.net/caomiao2006/article/details/51588838

  3. Java中实现序列化的两种方式 Serializable 接口和 Externalizable接口

    对象的序列化就是将对象写入输出流中. 反序列化就是从输入流中将对象读取出来. 用来实现序列化的类都在java.io包中,我们常用的类或接口有: ObjectOutputStream:提供序列化对象并把 ...

  4. 并发王者课-铂金1:探本溯源-为何说Lock接口是Java中锁的基础

    欢迎来到<并发王者课>,本文是该系列文章中的第14篇. 在黄金系列中,我们介绍了并发中一些问题,比如死锁.活锁.线程饥饿等问题.在并发编程中,这些问题无疑都是需要解决的.所以,在铂金系列文 ...

  5. K:java中的序列化与反序列化

    Java序列化与反序列化是什么?为什么需要序列化与反序列化?如何实现Java序列化与反序列化?以下内容将围绕这些问题进行展开讨论. Java序列化与反序列化 简单来说Java序列化是指把Java对象转 ...

  6. 在Java中进行序列化和反序列化

    对象序列化的目标是将对象保存在磁盘中,或者允许在网络中直接传输对象. 对象序列化允许把内存中的Java对象转换成平台无关的二进制流,从而允许把这种二进制流持久保存在磁盘上或者通过网络将这种二进制流传输 ...

  7. java中的序列化问题

    序列化就是一种用来处理对象流的机制,所谓对象流也就是将对象的内容进行流化,将数据分解成字节流,以便存储在文件中或在网络上传输.可以对流化后的对象进行读写操作,也可将流化后的对象传输于网络之间.序列化是 ...

  8. Java中的序列化与反序列化

    序列化定义 将对象转换为字节流保存起来,并在以后还原这个对象,这种机制叫做对象序列化. 将一个对象保存到永久存储设备上称为持久化. 一个对象要想能够实现序列化,必须实现java.io.Serializ ...

  9. java中的序列化和反序列化

    package cn.zhou; import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.Fil ...

随机推荐

  1. java解决回文数

    递归解决palindrome问题 如果String仅仅只是一个或者0个字符,则它就是palindrome 否则比较字符串第一个和最后一个字符 如果第一个和最后一个字符不同,那么就不是palindrom ...

  2. NUMA导致的MySQL服务器SWAP问题分析

    [作者] 王栋:携程技术保障中心数据库专家,对数据库疑难问题的排查和数据库自动化智能化运维工具的开发有强烈的兴趣. [问题描述] 我们知道当mysqld进程使用到SWAP时,就会严重影响到MySQL的 ...

  3. Hive数据导入/导出

    1.1 导入/导出规则 EXPORT 命令导出数据表或分区,与元数据一起输出到指定位置.又可以从这个输出位置移动到不同的Hadoop 或Hive 实例中,并且使用IMPORT 命令导入. 当导出一个分 ...

  4. mysql解压版服务启动方式

    使用mysql解压版,在不安装为windows服务时,使用下面的方式启动. 1.打开命令行,首先进入mysql解压目录的bin目录下 d:\mysql\bin 2.输入mysqld --console ...

  5. 混合事务分析处理“HTAP”的技术要点分析

    HTAP是近些年来比较火的一个概念,本文将聊聊HTAP的前世今生及技术特点. 一.数据应用类别 根据数据的使用特征,可简单做如下划分.在选择技术平台之前,我们需要做好这样的定位. 1.1 OLTP 联 ...

  6. spring注解方式,异常 'sessionFactory' or 'hibernateTemplate' is required的解决方法

    做单元测试的时候,抛出异常 Caused by: java.lang.IllegalArgumentException: 'sessionFactory' or 'hibernateTemplate' ...

  7. Python学习笔记整理总结【Django】【MVC/MTV/路由分配系统(URL)/视图函数 (views)/表单交互】

     一.Web框架概述  Web框架本质上其实就是一个socket服务端,用户的浏览器其实就是一个socket客户端. #!/usr/bin/env python # -*- coding:utf-8 ...

  8. asp.netcore 3.0 Docker Nginx(震惊,原来docker是这样的!)

    引言 Docker发布于2013年,Docker是dotCloud公司创始人在法国期间发起的一个公司内部项目,他是dotCloud多年云技术的一个革新.Docker在容器基础上进行了一步的封装,从网络 ...

  9. jedis 2.9版本部分属性变更

    1.控制一个pool可分配多少个jedis实例 “maxActive” -> “maxTotal” 2.最大建立连接等待时间.如果超过此时间将接到异常.设为-1表示无限制. “maxWait” ...

  10. 阿里云ECS服务器提示需要修复的漏洞问题

    1.漏洞: RHSA-2018:1842: kernel security, bug fix, and enhancement updateRHSA-2018:2299: NetworkManager ...