【问题标题】:What is the purpose of Serialization in Java?Java中序列化的目的是什么?
【发布时间】:2011-01-15 00:31:19
【问题描述】:

我已经阅读了很多关于序列化的文章,以及它如何如此出色和出色,但没有一个论点足以令人信服。我想知道是否有人真的可以告诉我我们可以通过序列化一个类来真正实现什么?

【问题讨论】:

  • 他“不相信”他们回答了他的问题。
  • 提供的答案实际上是正确的。如果他们不适合您,请以 cmets 的身份回复他们并尝试解决问题,而不是忽略他们,然后在他们指出您没有正确使用 SO 时开始抨击其他人。
  • Anon 通过阻止重复问题来提高网站的质量。看到五个不同的问题都在问同样的事情是很愚蠢的。如果您无法得到答案,那么有时就是这样。如果你得到了答案但它似乎不起作用,那么在 cmets 中继续讨论。 SO 不是一个神奇的盒子,如果你问对了问题,或者问了足够多的时间,或者引起了正确专家的注意,它就不会神奇地给你答案。
  • 要么:(接受答案)要么(发表评论和/或修改问题,解释为什么它不是你需要的)。
  • 似乎没有人指出你不序列化一个类,你序列化一个代表类实例的对象。也许这有助于了解它为什么有用?

标签: java oop object serialization stream


【解决方案1】:

让我们先定义序列化,然后我们可以谈谈为什么它如此有用。

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

我们为什么要这样做?

有几个原因:

  • 通信:如果您有两台机器运行相同的代码,并且它们需要通信,那么一种简单的方法是让一台机器使用它想要传输的信息构建一个对象,然后将其序列化反对另一台机器。这不是最好的沟通方式,但可以完成工作。

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

  • 深拷贝:如果您需要一个对象的精确副本,并且不想麻烦地编写自己的专用 clone() 类,只需序列化对象到一个字节数组,然后反序列化到另一个对象就达到了这个目的。

  • 缓存:实际上只是上面的一个应用程序,但有时一个对象需要 10 分钟才能构建,但反序列化只需 10 秒。因此,与其将这个巨大的对象保存在内存中,不如通过序列化将其缓存到一个文件中,然后在需要时将其读取。

  • 跨 JVM 同步:序列化跨可能在不同架构上运行的不同 JVM 工作。

【讨论】:

  • 什么东西需要 10 分钟才能完成?
  • 我的意思是(当然)序列化中涉及的文件 I/O 可能会使任何纯对象创建开销相形见绌。我想你可能在谈论一些计算上非常昂贵的东西,比如科学建模,但是序列化是一种非常糟糕的持久性机制,因为它难以处理模式更改
  • @oxbow_lakes 例如,如果您维护一组特定数据的索引以进行快速搜索。像这样的索引可能需要很长时间才能构建,但是一旦构建完成,它就可以相对快速地进行序列化/反序列化。
  • 如果 Web 应用请求在到达目的地之前必须通过地球上的每一个路由器,构建对象,使用尽可能长的路径返回对象,是的,这可能需要 10 分钟。
  • @Schmelter,既然你提到序列化不是最好的通信方法,那么这是最合适和最好的方法吗?
【解决方案2】:

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

【讨论】:

  • 那么,它似乎只是一种更好、更有效的方式将数据写入文件并在需要时将其读回?
  • 这是唯一真正的解释。我想不出任何其他真实世界的序列化应用 +1
  • 又短又甜。完美的解释。
【解决方案3】:

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

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

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

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

【讨论】:

  • 在这种情况下,为什么需要将它们存储在字节数组流中(使用序列化),是否比仅使用临时字段更简单?
【解决方案4】:

In essense:

序列化的过程 转换一组对象实例 包含相互引用的 成线性的字节流,其中 然后可以通过套接字发送, 存储到文件中,或者干脆 作为数据流进行操作

查看Wiki的用法:

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

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

【讨论】:

    【解决方案5】:

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

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

    【讨论】:

      【解决方案6】:

      序列化对象在空间中保持状态,它们可以通过网络、文件系统等传输......而且时间,它们可以比创建它们的 JVM 寿命更长。

      有时这很有用。

      【讨论】:

      • 这可以通过一个包含一些文本的简单文件来实现。读回序列化对象比读取写入文本文件的对象状态要容易一些,对吗?
      • @m_a_khan:哇。是的,它可以用一个简单的文本来完成。但是一旦对象变得更复杂,或者它们的结构(组合、继承)变得更复杂,手动(取消)编组它们就会变得很麻烦。想象一下将列表、集合和映射作为对象成员。
      • 很容易想出不同的序列化方案,而且确实有很多。出于非常充分的理由,它们都不会导致一般情况,即“简单文本”
      【解决方案7】:

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

      【讨论】:

      • 在我看来,序列化和使用单个配置对象作为参数是非常正交的。可能这不是一个典型的用例。
      【解决方案8】:

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

      另一方面,序列化将事物直接转化为计算机语言。这就像你用西班牙语告诉西班牙电脑一些东西,而不是用法语告诉它一些东西,强迫它学习法语,然后通过翻译所有内容将东西保存成它的母语西班牙语。不是技术最密集的答案,我只是想以通用语言格式创建一个易于理解的示例。

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

      【讨论】:

      • 在尝试用简单的英语表达时,您并没有真正以任何有用的方式解释序列化。
      猜你喜欢
      • 2010-10-11
      • 2011-07-12
      • 2012-01-17
      • 1970-01-01
      • 1970-01-01
      • 2010-10-21
      • 2013-08-01
      • 2011-03-20
      相关资源
      最近更新 更多