Java 中的序列化:您需要知道的一切 [2022]

已发表: 2021-01-04

随着 IT 行业的日益繁荣,我们对它的依赖似乎与日俱增。 这种稳定的增长促使许多在职专业人士开始使用编程语言,以期在行业内保持相关性。 虽然该行业使用多种语言为其客户提供服务,但其中几种语言的使用频率高于其他语言。 Java 就是这样一种语言。

无论您是新手还是老手,扎实的 Java 知识都将使您在软件之旅的每一个转折点上受益。 与任何其他编程语言一样,Java 也包含自己的综合教学大纲。 一个人必须每天练习这种语言,才能掌握所有标记语言的各种概念。 对用户有很大帮助的一个概念是 Java 中的序列化实践。

目录

介绍

Java上下文中的序列化是指将Java代码对象系统地转换为字节流的过程。 这样做是为了能够将所述目标代码从一个 Java 虚拟机高效地传输到另一个 Java 虚拟机。 随后,这允许在反序列化的帮助下重新创建它。 我们使用序列化来满足多个目标。 让我们看一下以下部分中最受欢迎和相关的内容。

为什么使用序列化?

将对象表示为字节序列的现象在编程范式中占有相当大的份额。 当该过程本身也扩展到表示对象的数据时,实用程序会增加许多倍。 下面列出了 Java 中序列化的一些最常见用途。

沟通

Java 中的序列化允许在多个计算机系统之间进行有效和迅速的通信。 这些单元利用对象序列化和传输来促进各种对象的同时共享和设计。 因此,这也会导致最终的顺利执行。 在海量数据库的情况下,序列化允许高度简化的对象处理方法。

缓存

从广义上讲,缓存是指通过在信息上投入最少的时间来存储信息以便稍后访问信息的方法。 Java 中的序列化通过最小化反序列化大对象所消耗的时间来提示缓存。 众所周知,与反序列化所需的时间相比,构建对象所花费的时间要多得多。 因此,序列化通过缓存混合中相对较大的对象来帮助优化这种时间消耗。

深拷贝

Java 中的深拷贝是指从树中复制对象的过程,该过程不依赖于可能会发生一定程度变化的任何先前版本。 通过采用序列化,这个克隆过程变得更加容易。 通过将对象序列化为字节数组,然后对其进行反序列化,用户可以获得所述对象的副本。

跨 Java 虚拟机同步

实践序列化的主要优势在于它使用户能够跨不同的 JVM 进行操作。 一旦采用序列化,这些 JVM 是否在相同或不同的架构和操作系统上工作都没有关系。

持久性

通过对对象应用序列化,可以直接存储项目的状态,而不会带来任何不便。 此外,它还允许用户将提及的状态保存在数据库中,以便以后在将来的任何时间点检索。

阅读:Java 序列化面试问答

序列化对象 - 涉及的过程

在继续序列化对象之前,我们首先需要确定它是否可序列化。 现在,我们如何确定呢? 当且仅当其类或其任何父类允许实现 java.io.Serializable 接口时,Java 中的对象才是可序列化的。 如果这些类也实现了它的子接口,也就是 java.io.Externalizable,那么也符合标准。

如上所述,跨 JVM 同步是使用序列化最有效的应用之一。 当我们序列化一个对象时,我们将这个对象的状态转换为字节流。 因此,我们可以将对象从一个 Java 虚拟机转移到另一个。 因此,这个字节流也可以转换回原始对象。

这种转换也称为反序列化。 它是序列化的逆过程,其中来自发送方的对象的字节流之前已经序列化,在接收端重新创建。

Java中序列化的优点

在前面几节讨论序列化的用途和应用时,我们已经阐明了它的各种优点。 现在是深入研究它们的时候了。

  • 序列化最显着的优势之一是它是一个内置功能。 要实现或执行序列化,您不需要借助任何第三方软件。
  • 即使对于初学者并且刚刚学习他们的绳索的用户来说,序列化也是一个相当容易学习和理解的过程。
  • 通常,来自不同编程背景的开发人员在必须处理新语言的细微差别时会接触到背景。 但是,在序列化的情况下,该过程是通用的,因此所有开发人员都非常熟悉。
  • 它不仅易于使用和实施,而且同样易于定制。
  • 目前,有许多关键技术在其操作中使用序列化。 这是因为被序列化的数据流支持加密、认证、压缩和安全的 java 计算。

Java中序列化的缺点

没有一种编程语言是百分百完美的,它们也不能声称是完美的。 因此,构成它们的概念和过程也并非没有自己的缺陷。 以下是与序列化过程相关的一些一般缺点。

  • 一些序列化过程也需要同时应用反序列化。 现在,应用反序列化的缺点是它会使对象变脆。 因此,永远无法完全确定所述对象是否会被有效地反序列化。
  • 当调用序列化过程时,会导致创建一堆瞬态变量。 这些瞬态变量在创建时会占用额外的内存空间。 但是,由于在这些过程中未调用构造函数,因此许多这些瞬态变量无法初始化。 随后,它们最终影响了标准 Java 流程的变体。
  • 对于所有的时间消耗优化,序列化过程在内存利用率方面越来越低效。
  • 序列化过程不为每个 Java 标准版提供任何转换控制机制。 因此,它不适合与需要并行访问而不需要第三方 API 的应用程序结合使用。
  • 在使用序列化时,通常必须在获得细粒度控制以访问对象方面做出妥协。

从实用的角度看序列化

到目前为止,我们已经将序列化过程作为一个理论概念进行了讨论,包括它的各种优点和缺点。 现在是深入讨论允许我们从实际角度可视化序列化及其实现的时候了。 下面列举几个案例,帮助我们理解序列化的实际实现。

必读:JavaBeans 属性和好处:你应该如何利用?

序列化和继承

Java中的继承被广泛定义为一个类获取或继承另一个类的方法和字段的现象。 继承属性的类称为子类,继承属性的类称为超类。 术语超类也可以与基类和父类互换使用。

我们的第一个案例处理超类上下文中的序列化。 一般来说,如果一个超类是可序列化的,那么它的子类也可以默认被认为是可序列化的。 当然,这只有在超类实现 Serializable 接口时才成立。 但是,在某些情况下,即使超类没有实现 Serializable 接口,子类也可以被序列化。

当子类设法以一种能力实现 Serializable 接口时,就会发生这种情况。 如果超类在任何情况下都没有实现Serializable接口,那么子类的对象可以在子类自己实现Serializable接口时手动序列化。

有时,用户也可能遇到第三种可能性。 当超类是可序列化的,但用户并不完全需要采用与子类相关的过程时,就会出现这种可能性。

在这样的情况下,有一些方法可以有意识地防止不需要的子类序列化。 这可以通过在子类中实现 writeObject() 和 readObject() 方法来完成。 然而,仅仅实现这些方法是不够的。 除了编写这些方法外,用户还必须确保上述方法不会从其实现中抛出 NotSerializableException。

在静态成员的帮助下进行序列化

当实现序列化过程时,它最终会忽略过程中的静态字段成员。 这主要是因为序列化作为一个过程在很大程度上与所讨论对象的最新状态有关。 结果,虽然与类的特定实例关联的数据被成功序列化,但与之相关的静态成员字段却没有。

关于 XML 文档的序列化

Java 对象到 XML 的序列化可以通过多种方式实现。 它们主要是在 XMLEncoder 和 XMLDecoder 的帮助下实现的。 将 Java 对象序列化为 XML 文档的主要目的在于尝试限制序列化过程固有的各种缺点。

序列化过程中最相关的问题之一是保存和恢复序列化对象的逻辑仅基于组成类的内部结构。 它没有考虑在保存对象和检索对象之间经过的时间内可能对这些类造成的任何更改。 随后,这将导致反序列化过程即将失败。

序列化也会引起版本控制问题。 当用户使用类的一个版本保存对象但尝试使用不同版本或新版本的类来反序列化同一类时,就会发生这种情况。 在这种情况下,反序列化过程也会失败。

因此,为了避免所有这些问题,一些用户更喜欢将对象序列化为 XML 文档,而不是采用将它们序列化为二进制格式的传统方法。 此外,将 Java 对象序列化为 XML 文档还可以确保对象变得可读,从而提高了便利性。

结帐:Java 面试问答

了解可外部化接口

Java 中的 Externalizable 接口与序列化接口非常相似。 不同之处在于它们提供定制序列化的能力。 externalizable 接口使您可以选择要存储在流中的对象,而序列化接口不授予您相同的权限。

可以利用 java.io 下的可外部化接口。 externalizable 接口也为用户提供了两种方法。 第一个是 public void writeExternal(ObjectOutput out) throws IOException。 另一种是 public void readExternal(ObjectOutput in) throws IOException。

序列化和外化的区别

除了提供定制序列化的能力之外,其他一些关键变量也将序列化和外部化区分开来。 以下部分将仔细研究它们。

执行

可序列化接口和可外部化接口之间的主要区别之一在于它们的实现。 externalizable 接口期望用户明确提及他们希望被序列化的对象。 当处理可序列化接口时,情况并非如此。 在可序列化接口中,所有对象和变量在运行时都被序列化,没有任何区别。

方法

Externalizable 接口主要由两个方法组成。 它们是 writeExternal() 方法和 readExternal() 方法。 另一方面,可序列化接口不包含任何方法。

过程

在可外部化的接口中执行序列化过程时,他们被赋予了自定义序列化的特权。 而在可序列化接口中,人们已经将自己置于默认的序列化过程中。

向后兼容性和控制

Externalizable 接口支持序列化,对相关版本控制没有任何保留。 这种方法的唯一问题是用户在序列化超类时必须对自己负责。 相反,序列化接口要求两端都存在相同版本的 JVM。 但是,它确实允许所有对象和类的默认序列化,包括超类。

公共无参数构造函数

在重构序列化对象时,外部化接口需要使用公共无参数构造函数。 这在序列化接口的情况下是不同的,它不明确需要无参数构造函数,而是利用反射来重构序列化的对象和类。

Java中的序列化:争议

有不少争议与 Java 中的序列化概念相关。 他们中的许多人首先关心的是删除序列化作为一个过程。 人们普遍认为,Oracle 的架构师长期以来一直在考虑从 Java 中删除序列化,因为他们认为这是 1997 年的一个可怕错误。

根据他们的研究,序列化过程的设计缺陷使得它们对数据本身构成威胁。 就此而言,Mark Reinhold 在 1997 年将几乎三分之一的 Java 漏洞归因于序列化过程,甚至表示商数也可能远不止于此。

因此,很有可能在即将到来的更新中,序列化作为一种​​结构将完全从 Java 的编年史中删除或替换。 这也可能是因为大多数专家不认为序列化是 Java 初学者可以在他们的项目中实现的理想选择。

另请阅读: Java 项目理念和主题

从世界顶级大学获得软件开发课程获得行政 PG 课程、高级证书课程或硕士课程,以加快您的职业生涯。

结论

对序列化的讨论和审议不能通过阐明一些最佳实践来结束。 以下是用户必须采用的一些方法,以确保为自己提供最佳体验。

  • 为了表示可序列化的字段,必须使用 javadoc@serial 标记。
  • 对于表示序列化对象的文件,最好使用 .ser 扩展名。
  • 通常,对静态或瞬态字段进行默认序列化的过程是不受欢迎的。
  • 除非绝对强制,否则在任何情况下都必须尽量避免可扩展类的序列化。
  • 在实现序列化时,必须确保避免内部类参与序列化过程。

如果您有兴趣了解有关 Java、OOP 和全栈软件开发的更多信息,请查看 upGrad 和 IIIT-B 的全栈软件开发执行 PG 计划,该计划专为工作专业人士设计,并提供 500 多个小时的严格培训, 9 个以上的项目和任务、IIIT-B 校友身份、实用的实践顶点项目和顶级公司的工作协助

为未来的职业做准备

立即申请软件工程硕士