自定义类实现序列化接口 java_如何使用Externalizable接口自定义Java中的序列化

319c3b4385474a344ae17910efdd855e.png

Java序列化过程的缺点

我们都知道如何使用Serializable接口序列化/反序列化一个对象,并且如何使用writeObject

和readObject方法自定义序列化过程。

但是这些自定义还不够,因为JVM可以完全控制序列化过程,而这些自定义逻辑只是默认序列化过程的补充。我们仍然必须通过调用ObjectOutputStream.defaultWriteObject()和ObjectInputStream.defaultReadObject()from writeObject和readObject方法使用默认的序列化逻辑。如果我们不调用这些默认方法,我们的对象将不会被序列化/反序列化。

默认序列化过程是完全递归的。因此,每当我们尝试序列化一个对象时,序列化过程会尝试使用我们的类(除了static和transient字段)序列化所有字段(原语和引用),这使得序列化过程非常缓慢。

现在,假设我们有一个包含许多字段的对象,由于某种原因我们不想序列化(这些字段将始终分配默认值)。使用默认的序列化过程,我们必须使所有这些字段都是瞬态的,但它仍然不会有效,因为会进行大量检查以查看字段是否是瞬态的。

正如我们所看到的,使用默认序列化过程有许多缺点,例如:

序列化的自定义是不够的,因为JVM可以完全控制序列化过程,而我们的自定义逻辑只是默认序列化过程的补充。默认序列化过程是完全递归和缓慢的。为了不对字段进行序列化,我们必须将其声明为瞬态,并且许多瞬态字段将再次使该过程变慢。我们无法控制字段的序列化和反序列化方式。默认序列化过程在创建对象时不会调用构造函数,因此它无法调用构造函数提供的初始化逻辑。什么是外化和可外化接口?

如上所述,默认的Java序列化效率不高。我们可以通过使用Externalizable接口而不是Serializable接口来解决其中的一些问题。

我们可以通过实现写自己的序列化逻辑外部化的界面和重写它的方法writeExternal()和readExternal()。但是使用这种方法,我们不会从JVM获得任何类型的默认序列化逻辑,我们需要提供完整的序列化和反序列化逻辑。

因此,非常有必要仔细编码和测试这些方法,因为它可能会破坏序列化过程。但是,如果正确实施,外部化过程与默认序列化过程相比非常快。

我们将使用下面的Employee类对象作为解释的示例:

98cc5242debd8d1565befa4b65c1d0ac.png

df467cc3d57f6162826641e05936c1f8.png

序列化如何与Externalizable接口一起使用

正如我们上面看到的,在我们的例子Employee类,我们可以通过实现写自己的序列化逻辑外部化的界面和重写它的方法writeExternal()和readExternal()。

该对象可writeExternal通过调用DataOutput其原始值的writeObject 方法 或调用 ObjectOutput 对象,字符串和数组的方法来实现 保存其内容的方法 。

该对象可以readExternal通过调用DataInput基本类型的方法以及 readObject 对象,字符串和数组来实现 恢复其内容的方法 。该 readExternal方法必须以相同的顺序读取值,并使用与写入的相同类型 writeExternal。

bc0fa4fbfc38556b9e2730516703676a.png

要将对象序列化和反序列化为文件,我们需要按照Serializable示例中的相同步骤进行操作,这意味着调用ObjectOutputStream.writeObject()并ObjectInputStream.readObject()在以下代码中完成:

c3c2d79d266ceac339b8da484bcb00af.png

该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克隆的强制条件。

aecd8508f1169cf0325f715451b791d8.png

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
1. 请介绍一下Java的特点和优势。 Java的特点和优势包括:面向对象、跨平台性、安全性、高性能、多线程、灵活性和易学性等。Java是一种解释型语言,可以在不同的操作系统上运行,它的安全性得到了很好的保障,同时也有很好的性能表现,支持多线程,可以进行分布式计算等。 2. 请介绍一下Java的多态性。 Java的多态性是指同一种行为或操作可以适用于不同的对象,即同一个方法可以被不同的对象调用,并且可以有不同的实现方式。多态性可以提高代码的复用性和可扩展性,使得程序更加灵活。 3. 请介绍一下Java的异常处理机制。 Java的异常处理机制是指在程序运行时,当发生错误或异常时,可以通过捕获和处理异常来保证程序的正常运行。在Java,异常分为可检查异常和不可检查异常,可检查异常需要在代码显式处理,而不可检查异常通常是由系统或硬件错误引起的,无法通过代码处理。Java的异常处理机制主要包括try-catch语句、finally语句和throw语句等。 4. 请介绍一下Java的线程同步。 Java的线程同步是指在多线程并发执行时,多个线程访问共享资源时需要进行同步,避免出现竞态条件和数据不一致等问题。Java的线程同步可以通过synchronized关键字、Lock接口和volatile关键字等实现。其synchronized关键字是最常用的同步机制,可以保证同一时刻只有一个线程执行同步代码块,从而保证线程安全。 5. 请介绍一下Java的对象序列化Java的对象序列化是指将Java对象转化为字节序列以便于在网络传输或保存到文件,同时也可以将字节序列反序列化Java对象。Java的对象序列化可以通过实现Serializable接口实现,同时也可以通过实现Externalizable接口自定义序列化过程。对象序列化可以实现对象的持久化、分布式计算和远程调用等功能。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

零溢

你的鼓励将是我创作的最大动力

¥2 ¥4 ¥6 ¥10 ¥20
输入1-500的整数
余额支付 (余额:-- )
扫码支付
扫码支付:¥2
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、C币套餐、付费专栏及课程。

余额充值