默认序列化如何破坏封装?

5

我经常听到人们说序列化破坏了封装性,而通过提供自定义序列化可以在一定程度上减少这种封装的损失。能否提供一个具体的例子来证明由于默认序列化而导致封装丧失的现象,并说明如何通过采用自定义序列化来减少这种丧失?

我将此问题标记为与Java相关,但答案可能与语言无关,因为我认为这是跨平台和语言的共同问题。


1
这篇文章提供了一个很好的例子,说明序列化如何破坏封装性。 - Darshan Mehta
2个回答

2
优秀的问题!首先,让我们定义一下封装并从那里开始。这篇维基百科文章给出了以下的封装定义:(链接)
  • 一种限制对象组件访问的语言机制。
  • 一种语言结构,有助于将数据与操作该数据的方法(或其他函数)捆绑在一起。
至少从Java的角度来看,序列化对这两个概念都有影响。当你在Java中实现Serializable接口时,你实际上是告诉JVM,你所有非瞬态成员变量和它们声明的顺序定义了从字节流重构对象的合同。如果且仅当你的所有成员变量的类定义也实现了Serializable,这将递归地起作用,而这就是你可能会遇到麻烦的地方。
封装问题
基于前面的封装定义,特别是第一个条目,封装防止你了解处理对象的底层情况,尤其是关于它的成员变量。正确实现Serializable迫使开发人员了解比他们在功能上关心的对象更多的信息。从这个意义上说,实现Serializable直接反对封装。
自定义序列化
在每种情况下,序列化都需要知道哪些数据构成特定类型的“对象”。Java的Serializable接口通过强制您了解希望序列化的每个Object的瞬态状态来将其推向极端。你可以通过定义一个外部的序列化机制来避免这个问题,但是这样做会有设计上的权衡——例如,你可能需要处理它们实现的接口级别而不是直接与它们的成员变量交互,并且你可能会失去一些从序列化字节流中重构完整Object类型的能力。

0
Java默认序列化按字段写入和读取,这样会暴露对象的内部结构,破坏封装性。如果更改类的内部结构,则可能无法正确恢复对象状态。而使用自定义序列化,如果更改了类,则可以尝试更改readObject,以便正确恢复保存的对象。

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