在Java中需要序列化

谁能告诉我什么是Java的序列化的需要和一个示例场景来解释的需要。 我不需要定义。

当需要通过networking发送数据或存储在文件中时,通常使用序列化。 数据我的意思是对象而不是文本。

现在的问题是你的networking基础设施和你的硬盘是硬件组件,理解位和字节,但不是JAVA对象。

序列化是将Java对象的值/状态转换为字节,以通过networking发送或保存。

这与您的语音通过PSTN电话线传输的方式类似。

关于序列化的简短故事

经过多年的努力,地球科学家研制出了一个能帮助他们日常工作的机器人。 但是这个机器人比火星上的科学家开发的机器人要less。

在两个行星的科学家会面之后,火星决定把他们的机器人送到地球。 但是发生了一个问题。 发送100个机器人到地球的成本是1亿美元。 大约需要60天的旅行。

最后,Mar的科学家决定与地球科学家分享他们的秘密。 这个秘密是关于class级/机器人的结构。 地球科学家在地球本身上发展出同样的结构。 Mar的科学家每个机器人的数据序列化并将其发送到地球。 地球的科学家对数据进行反序列化 ,并相应地将数据送入每个机器人。

这个过程为他们节省了大量的数据传输时间。

一些机器人正在火星上进行一些防御工作。 所以他们的科学家们把这些机器人的一些重要特性标记为短暂的,然后将数据发送到地球。 请注意,当对象被反序列化时,transient属性被设置为null(在引用的情况下)或默认值(在基本types的情况下)。

地球科学家还注意到的另一点是,火星的科学家们要求他们创造一些静态variables来保持环境的细节。 这些细节被一些机器人使用。 但是,火星的科学家们不会分享这些细节。 因为地球的环境与火星的环境不同。

即使知道机器人的类别结构和序列化的数据,地球的科学家也无法对可以使机器人工作的数据进行反序列化。

Exception in thread "main" java.io.InvalidClassException: SerializeMe; local class incompatible: stream classdesc : 

火星的科学家正在等待完整的付款。 一旦付款完成,火星的科学家们与地球科学家分享了一系列的统一标识符。 地球的科学家将其设置为机器人课程,一切开始工作。

Java序列化(特别是Serializable和Exernalizable接口)允许读/写任意复杂的Java对象,自动或手动从/到/到磁盘或从/到networking。 XML和JSON是文本格式,Java序列化是二进制格式。 (序列化也是简单读/写数据的一般概念,但是由于问题是关于Java的,我假设你指的是内置的序列化系统,即Serializable / Exernalizable)

“实现可序列化”优于XML / JSON
起初,你可以免费获得序列化。 您不需要对对象进行很多更改,以便让序列化机制与它一起工作。 另一个优点是,因为它是一种二进制格式,所以它比文本格式要紧凑得多,所以可能会占用较less的空间(这对于节省networking带宽或节省磁盘上的存储空间是很好的)。

缺点“通过XML / JSON实现Serializable”
内buildJava序列化的缺点是,如果对对象进行更改,使不同的序列化格式兼容可能真的是一个重大的噩梦。 而且,虽然您可以手动编辑XML和JSON,但不能编辑序列化的Java对象(无需将其读入Java)。 出于同样的原因,debuggingXML和JSON通常比二进制格式更容易,因为XML和JSON是可读的。 Java的内build序列化机制的另一个缺点是你不能(轻易地)序列化/反序列化来自另一种编程语言的数据。

用于读取/写入数据的替代技术
除了Java的内置序列化之外,还有其他可选的序列化技术,这两种技术为您提供了两全其美的优点:紧凑的二进制格式,语言互操作性,易于版本兼容性以及经常使用的debugging工具,以便以可读的格式转储二进制数据。 例如,Google的开源协议缓冲区和MessagePack就是序列化库/格式的例子,它们可以让你读/写紧凑的二进制数据并且容易地维护版本的兼容性。 这些库比内置的Java序列化最大的缺点是它们涉及用于序列化的普通旧数据对象(相对于也具有与其相关行为的更全面的Java对象)。 然而,这个缺点实际上是将存储信息的数据模型与从其包装或从中派生出来的对象分开的优点,实际上是一种很好的编程实践,并且使支持多种格式变得更容易。

用法
既然你问了需要,不仅仅是定义,还有一些用例:

  1. 只需保存您的数据以备后用。 例如,假设你正在写一个电子游戏。 你的程序不会永远运行; 即使它从不崩溃(希望是这种情况),用户可能会在某个时候退出程序,或者操作系统可能会终止程序以节省资源(例如,在Android上,用户没有与之交互的后台进程频繁并被操作系统故意杀死,像RAM一样回收系统资源)。 为了确保用户从一开始就不会启动,而是从最初的保存点或者从最近的保存点恢复,您需要将游戏状态写入永久存储器(即硬盘驱动器,用户的Google云端硬盘帐户等)。 为了做到这一点,你需要将表示游戏状态的内存中的数据结构转换成可以写入磁盘(或者保存数据的任何系统)的原始字节。

  2. 从远程服务器检索信息。 让我们继续游戏的例子…假设你正在创build一个在线多人游戏,或者你希望能够在游戏中提供新的关卡或物品,而不需要用户更新他们的应用程序。 为此,您需要从服务器计算机(您用作各种设备上安装的应用程序的所有副本的联系点)传送有关在线播放器的信息或有关新级别/项目的信息,到应用程序的个人副本。 服务器和应用程序都需要某种forms的这些数据结构的内存中表示(例如,其他玩家的位置,新级别的结构,新项目的描述/图像等),但是要传送信息从服务器到设备上的应用程序,通信系统由原始字节组成,因此必须有一种方法将数据转换为原始字节,并将原始字节转换回有意义的内存数据结构。

几乎任何两个不同的进程/应用程序之间或应用程序与某个存储系统之间的任何通信都是需要某种序列化机制的情况。

当你想把一个对象的状态保存到一个文件中或通过networking发送时,你需要把它转换成一系列的字节。 这被称为序列化。

Java有一个内置机制,其他选项包括XML或JSON。

当你需要这个的例子:caching对象,进行远程方法调用,将对象图保存到磁盘。

  • 如果你想在磁盘上存储一个对象( – 结构),你需要序列化。
  • Web服务需要将对象序列化为xml,然后才能传输。

你也可以使用序列化实现对象克隆

序列化通常被称为Object in到一系列位的转换。 这是在java中的一个必不可less的一个,因为java主要意味着基于Web的应用程序,我的意思是使数据在networking上可用