Effective Java: (86) Implement Serializable with great caution

Item 86: Implement Serializable with great caution

序列化一个类只需要简单声明让其实现Serializable接口即可。看起来如此简单以至于被误认为实现序列化对程序员来说很容易。事实却复杂得多,即时代价也许可以忽略,但长期代价却很昂贵。

主要代价之一是:一旦实现了Serializable序列化接口,发布后的类也就丧失了灵活性。序列化成为暴露的API的一部分。如果采用了序列化的默认实现,当前类的私有字段也成为了API的一部分。采用默认序列化实现后,如果后续修改了类的内部表现(internal representation),将导致序列化失败。

所以实现序列化接口后,应当仔细设计序列化实现——尽管这将增加一开始时的开发成本,但值得这么做。

实现了序列化接口的类的演化的限制之一是“流统一标识符”(stream unique identifiers),更通用的名称是“序列号”(serial version UID)。每个序列化类都有一个独特的标识符。如果没有声明一个静态final类型的long变量serialVersionUID,系统将在运行时通过SHA-1算法生成这个参数值。类名、实现的接口、大部分成员变量以及编译器生成的合成对象都将影响这个变量的值。如果其中任何一个项目有变化——例如增加一个方法——最终的UID都将发生变化。将抛出InvalidClassException异常

第二个代价是实现序列化后提高了出现安全漏洞和bug的可能性。通常类初始化通过构造函数,但序列化提高了“语言之外的机制”(extralinguistic mechanism)完成类初始化动作。

第三个代价是增加了测试成本。新版本发布后,需要验证高低版本之间的序列化转换是否成功。随着版本的增加,序列化的测试成本是指数级的。

©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

相关阅读更多精彩内容

友情链接更多精彩内容