使用序列化是个好主意吗?

3

关于序列化,存在几个风险,包括不兼容的更改。如果在被序列化的类中发生不兼容的更改,则即使具有静态final long serialVersionUID字段,我们也无法对其进行反序列化。

那么,序列化的替代方案是什么?XML?如果有任何替代方案,那么在现实世界的项目中是否有任何序列化的用途呢?


在什么上下文中?持久性?网络?... - Puce
1
使用XML只是一种不同的序列化格式。Java也支持XML序列化(内置)。 - Peter Lawrey
@DebadyutiMaiti 当然,不兼容更改存在问题。但是删除字段对于对象序列化来说并不是一种不兼容的更改。正如我上面所说,您需要了解什么是不兼容的更改和什么不是。目前,您还不知道。对象序列化还处理循环图。您需要停止猜测所有这些,并阅读对象序列化规范。我在这里也没有提到JAXB。 - user207421
@EJP,实际上你在之前的评论中提供的链接[http://docs.oracle.com/javase/6/docs/platform/serialization/spec/version.html#6678]包含“删除字段”主题,是“Incompatible changes”主题下的第一个主题。但是你说“删除字段对于对象序列化来说不是一种不兼容的更改”。那么为什么它会出现在该链接的“不兼容的更改”部分下呢? - Debadyuti Maiti
@DebadyutiMaiti 正如所述,这是一种“不兼容的更改”,即某些值将采用其默认值。根据你的说法,它并不是一种“不兼容的更改”防止对象被反序列化,这是错误的,且仍然是错误的。我不负责 Javadoc 的组织和编写方式,因此问我为什么是徒劳的。 - user207421
显示剩余6条评论
3个回答

3

当然,Java序列化有替代品:XML(如您所述),JSON,protobuf,还有其他任何您想使用的。

所有这些方法都存在一定的不兼容风险。我认为没有其他方法中的魔法。如果您向对象添加新属性,则必须处理“鸭子类型”。如果删除了一个必需的属性,则所有方法都会出现问题。


协议已更改为IIOP。 - user207421

2
你好,看起来你将序列化和数据格式混淆了 - 最好分开讨论。
大体上有三种序列化方式:
1.自动、全面、低级别 - 这很有用,因为它可以作为一项服务提供,并且使用起来需要很少的努力。但是,由于其本质与语言/程序中使用的内部格式密切相关,如果内部格式发生变化,则反序列化将会很困难。典型的例子是Java和Python提供的“本地”序列化; 它对程序状态的短期快照非常有用。
2.自动、受限、中级别 - 通常用于通信/互操作。这不支持语言的所有功能,可能仅允许保存简单的数据结构。如果足够使用,则它是一个有用的中间地带,因为它可以自动化,但独立于语言的内部格式(但不一定独立于程序的细节)。典型的例子包括协议缓冲区、Thrift和JSON库(不是JSON本身,JSON只是一种数据格式…); 显然,这对于通信和自定义数据存储非常有用。
3.“手工编码”的高级别 - 这需要更多的工作,可能保存的信息较少,但旨在以独立于程序(或语言)使用的内部格式的方式提取“重要部分”。示例包括Docbook或OpenDocument(JAXB在默认情况下提供了接近(1)的支持,但需要小心使用才能接近(3)); 这对于长期数据归档非常有用,通常与“官方”规范相关联。
上述内容与用于编码序列化数据的数据格式无关。我相信你可以将所有内容实现为XML; JSON通常用于(2)。
无论如何,回答问题 - (1)存在您所指出的问题。如果(2)足够,那么这是一个简单的解决方案(但如果程序中的数据结构发生变化,则仍然会受到(1)的某些问题的影响)。否则,您需要执行(3)所隐含的额外工作。

1

答案取决于你的目标。如果你在Java进程之间发送数据,那么默认的Java序列化机制可能可以很好地工作。

然而,对于存储数据,特别是人类可能想要查看或编辑的数据,Java序列化机制并不适合。

有许多基于XML的Java序列化库非常出色,当需要人类可读/可编辑的输出时,我非常喜欢使用它们。

其中两个很棒的是:XStreamJAXB


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接