Java序列化的目的是什么?


105

我已经读了很多关于序列化的文章,它是如此的好和很棒,但是没有一个论点令人信服。我想知道是否有人真的可以告诉我通过序列化类可以真正实现的目标?


10
他们的论点有什么“说服力”?您为什么还没有接受问题的任何答案?
Anon。

8
他“不相信”他们回答了他的问题。
Anthony Forloney,2010年

5
实际上,所提供的答案是正确的。如果他们不适合您,请以评论的形式回复他们,并尝试解决问题,而不仅仅是忽略他们,然后在他们指出您使用的不正确时就开始抨击其他人。
Anon。

4
Anon鼓励重复的问题,以提高网站的质量。看到五个单独的问题都在问同一件事是很愚蠢的。如果您找不到答案,那么有时候就是这样。如果您得到答案,但似乎无法解决问题,请继续在评论中进行讨论。因此,如果您只是提出正确的问题,或者问了足够多的时间,或者引起了正确专家的注意,那么这并不是一个神奇的盒子,不会神奇地为您提供答案。
克里斯,2010年

1
要么:(接受答案),要么(发表评论和/或修改问题,解释为什么它不是您所需要的)。
Anon。

Answers:


182

让我们先定义序列化,然后再讨论为什么它如此有用。

序列化只是将现有对象转换为字节数组。此字节数组表示对象的类,对象的版本以及对象的内部状态。然后可以在运行相同代码的JVM之间使用此字节数组来传输/读取对象。

我们为什么要这样做?

有以下几个原因:

  • 通信:如果您有两台运行相同代码的计算机,并且它们需要进行通信,则一种简单的方法是,一台计算机使用要传输的信息来构建对象,然后将该对象序列化到另一台计算机。这不是最佳的沟通方式,但可以完成工作。

  • 持久性:如果要将特定操作的状态存储在数据库中,则可以轻松地将其序列化为字节数组,然后存储在数据库中以供以后检索。

  • 深度复制:如果您需要对象的精确副本,并且不想麻烦编写自己的专门clone()类,只需将对象序列化为字节数组,然后将其反序列化为另一个对象可以实现此目标。

  • 缓存:实际上只是上述应用程序,但有时一个对象需要10分钟的构建时间,而反序列化则只需10秒。因此,与其保留内存中的巨型​​对象,不如通过序列化将其缓存到文件中,并在以后需要时将其读入。

  • 跨JVM同步:序列化可在可能在不同体系结构上运行的不同JVM之间进行。


62
到底需要10分钟才能建成?
oxbow_lakes

2
我的观点是(当然)串行化中涉及的文件I / O可能会使纯对象创建的开销相形见war。我想您可能正在谈论一些计算量非常大的东西,例如科学建模,但是序列化由于很难处理模式更改而导致持久性的机制非常差
oxbow_lakes 2010年

11
@oxbow_lakes例如,如果您维护特定数据集的索引以进行快速搜索,则可能是一个例子。像这样的索引可能要花很长时间才能建立,但是一旦建立,就可以相对快速地进行序列化/反序列化。
大卫2010年

如果Web应用程序请求必须先到达地球上的每个路由器,然后再到达目的地,即构建对象,然后使用最长的路径将其与对象一起返回,是的,可能需要10分钟。
Vaibs

@Schmelter,既然您提到了序列化不是通信的最佳方法,那么哪种方法才是最佳的实现方法呢?
Ashfaque Rifaye

58

在运行应用程序时,其所有对象都存储在内存(RAM)中。当您退出时,该内存将被操作系统回收,并且您的程序实质上会“忘记”运行时发生的所有事情。序列化通过让您的应用程序将对象保存到磁盘,以便下次启动时可以将其读回来解决此问题。如果您的应用程序将提供保存/共享先前状态的任何方式,则需要某种形式的序列化。


2
因此,似乎这是一种将数据写入文件并在需要时回读的更好,更有效的方法?
m_a_khan'2

1
这是唯一的真实解释。我想不出任何其他现实世界中的序列化+1应用程序
艾米丽(Emily),

简短而甜美。完美的解释。
Yakhoob

21

我可以分享我的故事,并希望它能提供一些为什么需要序列化的想法。但是,您的问题的答案已经非常详细。

我有几个项目需要加载和读取一堆文本文件。这些文件包含停用词,生物医学动词,生物医学缩写,彼此语义相关的词等。这些文件的内容很简单:单词

现在,对于每个项目,我需要从每个文件中读取单词,并将它们放入不同的数组中。由于文件的内容从未更改,因此在第一个项目之后,它成为一项常见但又多余的任务。

因此,我要做的是创建了一个对象来读取每个文件并填充单个数组(对象的实例变量)。然后我序列化了对象,然后为以后的项目简单地反序列化了它们。我不必读取文件并一次又一次地填充阵列。


1
在这种情况下,为什么需要将它们存储在字节数组流中(使用序列化),这比仅使用临时字段更简单吗?
kidnan1991 '18

3

本质上

序列化是将一组包含彼此引用的对象实例转换为线性字节流的过程,然后可以通过套接字将其发送,存储到文件或简单地将其作为数据流进行操作

查看Wiki的用法:

序列化有许多优点。它提供:

  1. 一种持久化对象的方法,它比将其属性写入磁盘上的文本文件更方便,并通过读回该对象来重新组装它们。
  2. 发出远程过程调用的方法,例如在SOAP中
  3. 一种分配对象的方法,尤其是在诸如COM,CORBA等软件组件中的对象。
  4. 一种检测时变数据变化的方法。

1

最明显的是,您可以通过网络传输序列化的类,而收件人可以构造原始实例的副本。同样,您可以将序列化的结构保存到文件系统。

另外,请注意,序列化是递归的,因此,如果需要,您可以在一个膨胀开关中序列化整个异构数据结构。


0

序列化的对象在空间中保持状态,可以通过网络,文件系统等进行传输……而且时间还可以,它们可以超过创建它们的JVM。

有时这很有用。


这可以通过包含一些文本的简单文件来实现。回读序列化的对象然后读取写入文本文件的对象的状态要容易一些,对吗?
m_a_khan'2

@m_a_khan:哇。是的,可以使用简单的文本完成。但是,一旦对象变得更复杂,或者它们的结构(组合,继承)变得更好,它就将成为手动(取消)编组对象的麻烦。想象一下将列表,集合和映射作为对象成员。
Dirk Schumacher 2014年

容易想到不同的序列化方案,并且确实存在许多方案。出于非常好的原因,它们都不以一般文本的形式出现在“简单文本”中
David Soroko 2014年

0

我使用序列化的对象来标准化传递给函数或类构造函数的参数。传递一个序列化的bean比一长串参数要干净得多。结果是更易于阅读和调试的代码。


1
在我看来,分层和使用单个配置对象作为参数是非常正交的。可能这不是典型的用例。
的Gabor Bakos的

0

为了学习的简单目的(注意,我说学习,我说的不是最好的,甚至不是很好的,只是为了理解东西),您可以将数据保存到计算机上的文本文件中,然后有一个程序读取该信息,并基于文件,您可以让程序做出不同的响应。如果您更高级,则不一定是txt文件,而是其他东西。

另一方面,序列化将事物直接放入计算机语言中。就像您是在用西班牙语告诉西班牙计算机,而不是用法语说,是强迫它学习法语,然后通过翻译所有内容将其保存为西班牙语。这不是技术密集程度最高的答案,我只是想以一种通用语言格式创建一个易于理解的示例。

序列化也更快,因为在Java中,对象是在堆上处理的,并且比在堆栈上将它们表示为原语的时间要长得多。速度,速度,速度。从程序员的角度来看,文件处理更少。


在尝试用简单的英语表达事物时,您实际上并没有以任何有用的方式解释序列化。
user3516726
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.