我经常听到人们说序列化破坏了封装,并且通过提供自定义序列化可以在一定程度上最大限度地减少这种封装的损失.有人能提供一个具体的例子来证明由于默认序列化而导致的封装丢失,以及如何通过自定义序列化来最大限度地减少这种损失?
我将此问题标记为与Java相关,但答案可能与语言无关,因为我认为这是跨平台和语言的常见问题.
最佳答案 好问题!首先,让我们得到封装的定义并从那里开始.
This wikipedia article以下列方式定义封装:
>一种用于限制对某些对象组件的访问的语言机制.
>一种语言结构,便于将数据与对该数据进行操作的方法(或其他功能)捆绑在一起.
序列化,至少就像Java那样,对这两个概念产生了影响.当您在Java中实现Serializable接口时,您实际上是告诉JVM,所有非临时成员变量及其声明顺序定义了可以从字节流重构对象的契约.当且仅当您的所有成员变量的类定义也实现Serializable时,这会递归地工作,这是您可能遇到麻烦的地方.
封装问题
基于先前的封装定义,特别是第一项,封装使您无法了解您正在处理的对象如何在其成员变量方面实际工作.实现Serializable“正确”会迫使您作为开发人员更多地了解您正在处理的对象,而不是您在功能意义上可能关心的对象.从这个意义上讲,实现Serializable直接反对封装.
自定义序列化
在每种情况下,序列化都需要知道哪些数据构成特定类型的“对象”. Java的Serializable接口通过强制您了解希望序列化的每个Object的每个成员变量的瞬态,将此发挥到极致.您可以通过定义需要序列化的类型外部的序列化机制来解决这个问题,但是会有设计权衡 – 例如您可能需要在它们实现的接口级别处理对象而不是与其成员变量直接交互,并且您可能失去从序列化字节流重建确切对象类型的一些能力.