序列化:
将对象编码成一个字节流,以及从字节流编码中重新构造对象.
将一个对象编码成一个字节流称为序列化,相反的处理过程称为反序列化.
54:=======
实现序列化的代价:
1.一旦一个类发布,则改变这个类的灵活性将大大降低. 字节流编码变成了它的导出API的一部分.指:类自身的演变和类所在继承体系的演变(对子类序列化所加的影响).
2.它增加了错误(bug)和安全漏洞的可能性. 通常情况下对象是由构造方法来创建,序列化机制是一种语言之外的对象创建机制.
反序列化机制实际上是一个以字节流为入参的“隐藏的构造方法”, 要记住的是readObject方法和构造方法在逻辑上遵守的规则是一致的.
3.随着一个类的新版本的发行,相关的测试负担增加了.
55:====
考虑使用自定义的序列化形式:
1.若没有认真考虑默认序列化形式是否合适,则不要接受这种形式.
对于一个对象来说,理想的序列化形式应该只包含该对象所表示的逻辑数据,而逻辑数据与物理表示应该是独立的.
2.如果一个对象的物理表示等同于它的逻辑内容,则默认的序列化形式可能是合适的.如Person类,默认序列化是合理的.
3.即使你确定了默认序列化形式是合适的,通常你仍然要提供一个readObject方法以保证约束关系和安全性.
这也可以说是对入参的合法性检查. readObject要根据从字节流中获得的信息来构造对象,其本身就是一个构造方法.
4.当一个对象的物理表示与它的逻辑数据内容有实质性的区别时,使用默认序列化形式有4的问题. (类的逻辑表示表达类的一种用途,物理表示是实现逻辑表示的实现,不要让逻辑表示束缚在物理表示格式上)
4.1它使这个类的导出API永远的束缚在该类的内部表示上.
4.2它要消耗过多的空间.
4.3它要消耗过多的时间.
4.4它会引起栈溢出.
总而言之:当你决定要将一个类做成可序列化的时候,请仔细考虑应该采用什么样的序列化形式,只有当默认的序列化形式能够合理地描述状态的时候,你才使用默认的序列化形式,否则就设计一个自定义的序列化形式,通过它合理地描述对象的状态。你应该分配足够多的时间来设计一个类的序列化形式,就好像你分配足够多的时间来设计它的导出方法一样。正如你无法在将来的版本中去掉导出方法一样,你也不能去掉序列化形式中地域,它们必须被永久地保留下去,以确保序列化兼容性(serialization compalibility).选择错误的序列化形式对于一个类的复杂性和性能都会有永久的负面影响.
56。========
readObject方法与构造方法所受的约束相同.它相当于另一个公有的构造方法.不严格的说readObject 是一个"用字节流作为唯一参数"的构造方法.
当一个对象被反序列化的时候,对于客户不应该拥有的对象引用,如果哪个域包含了这样的对象引用,则必须要做保护性拷贝,这是非常重要的.(就像封装集合的作法:要么返回一个只读集合,要么返回一个保护性拷贝的集合,以保证对象内部的集合状态不会被外部修改)
57。======
必要时提供一个readResolve方法.
任何一个readResolve方法,不管是显式的还是默认的,它都会返回一个新建的实例,这个新建的实例不同于该类初始化时刻创建的实例。(一个Singleton如果实现了Serializable接口,则一定要提供一个readResolve方法,以保证在反序列化后实例仍然只有一个.)
public class Singleton implements Serializable {
private static final Singleton SINGLETON= new Singleton();
private Singleton() {}
public static Singleton getInstance() {
return SINGLETON;
}
//该方法忽略掉被反序列化的对象,简单地返回该类初始化时刻创建的那个特殊的实例.因此此类的序列化形式并不需要包含任何实际的数据;所有的实例域都应该被标记为transient.
private Object readResolve() throws IOException {
return SINGLETON;
}
}
readResolve方法不仅对于singleton对象是必要的,而且对于所有其他的实例受控的(instance-controlled)类也是必需的.另一个例子是类型安全枚举类型(typesafe enum),它的readResolve方法必须返回代表特定枚举常量的规范的实例(canonical instance).凭经验,如果你正在编写的可序列化的类没有包含公有的或者受保护的构造方法,那么请考虑它是否需要一个readResolve方法.
readResolve方法的第二个用法是,作为保护性的readObject方法的一种保守的替代选择.
readObject 是另一个构造方法,
readResolve是静态工厂方法
总而言之:无论是singleton还是instance-controlled的类,都要使用readResolve来保护"instance-control invariant"
从本质上讲,readResolve方法把readObject方法从一个事实上的公有构造方法变成一个事实上的公有静态工厂。对于那些禁止包外继承的类而言,readResovle方法作为保护性的readObject方法的一种替代选择,也是非常有用的.
分享到:
相关推荐
Python的序列化与反序列化是将数据结构或对象转换为可存储或传输的格式,然后再次转换回原数据的过程。这一过程对于保存程序状态、跨进程通信、数据持久化等场景非常有用。Python提供了多种序列化库,如pickle、json...
而“【笔记】序列化和反序列化.docx”可能包含作者对学习过程的总结和心得,对于深入理解这些概念很有帮助。“01预习资料.docx”可能提供了基本的概念介绍,是学习序列化和反序列化的好起点。 总的来说,序列化和反...
Java中的序列化是一种将对象的状态转化为可存储或可传输的形式的技术。这主要涉及到将对象转换为字节流,以便可以在网络上发送,或者保存到文件系统中,之后再通过反序列化恢复为原来的对象状态。序列化对于实现跨...
了解序列化与反序列化,使用 印象笔记 打开,谢谢!
在Java编程中,序列化是将对象的状态转换为字节流的过程,以便可以存储...同时,`json 学习笔记.doc`文档可能包含有关JSON序列化和反序列化的额外信息,这在现代Web开发中是非常重要的,因为JSON是数据交换的常见格式。
"Memo"这个文件可能是包含有关序列化技术的笔记、代码示例或者教程,由于无法直接查看具体内容,我将基于常规的序列化知识进行详细解释。 序列化的主要应用场景有: 1. **持久化存储**:当需要将对象存储到硬盘上...
日常笔记-JAVA序列化
通过XML,开发者可以方便地序列化和反序列化笔记对象,实现数据的保存和加载。 接着,数据库知识也在本项目中扮演了重要角色。尽管“数据库”标签并未明确指出使用了哪种数据库,但通常在开发笔记应用时,为了实现...
031217_【第12章:JAVA IO】_对象序列化笔记.pdf 031218_〖第12章:JAVA IO〗_实例操作—单人信息管理程序笔记.pdf 031219_〖第12章:JAVA IO〗_实例操作:投票程序笔记.pdf 031301_【第13章:Java类集】_认识类集、...
4. **Java IO**:031203_【第12章:JAVA IO】_字节流与字符流笔记.pdf 和 031217_【第12章:JAVA IO】_对象序列化笔记.pdf,IO是Java中处理输入输出的重要模块,这里讲解了字节流和字符流的区别与使用,以及如何实现...
【第12章:JAVA IO】章节深入探讨了JAVA的输入输出系统,031203_【第12章:JAVA IO】_字节流与字符流笔记.pdf和031217_【第12章:JAVA IO】_对象序列化笔记.pdf,讲述了如何读写文件、处理字节流和字符流,以及对象...
"031217_【第12章:JAVA IO】_对象序列化笔记.pdf"涉及对象序列化,这是将Java对象转换为字节流以便存储或在网络上传输的过程。"031214_【第12章:JAVA IO】_压缩流笔记.pdf"可能涵盖如何使用Java IO进行数据压缩...
java序列化资料 主要是记录的一些笔记的东西。给自己保存的
在实际编程中,JSON.js文件可能包含了一个自定义的JSON序列化类,这个类提供了一些方法来实现JSON的序列化和反序列化操作。例如,它可能包含以下功能: - `serializeObject(object)`: 将JavaScript对象转换为JSON...
缓冲流、转换流、序列化流、打印流 缓冲流是对基本流的增强,能够高效读写数据。它创建一个内置的默认大小的缓冲区数组,通过缓冲区读写,减少系统IO次数,从而提高读写的效率。缓冲流分为字节缓冲流和字符缓冲流两...
此外,可能还使用了JSON格式来序列化和反序列化笔记数据,便于在本地存储或发送到服务器。 Bootstrap是Twitter开发的一个开源前端框架,它提供了一套完整的响应式设计、移动设备优先的Web开发解决方案。在"魔术笔记...
运行时序列化 在运行时高效地序列化数据和场景! 运行时序列化提供了强大,... •提供序列化回调笔记: •Metro / WP8平台不支持Hashtable和Arraylist类,因此我们不支持上述类型的序列化。 随时使用分享您的反馈意见
序列化通常通过`DECLARE_SERIAL`和`IMPLEMENT_SERIAL`宏实现,序列化过程主要通过`Serialize`函数完成。 综上所述,MFC不仅简化了Windows应用程序的开发,还提供了丰富的类库和工具,帮助开发者快速构建功能丰富的...
● 屏蔽byte[]数据类型,所有实现了序列化接口的对象均可直接在Redis进行读写 ● 保留String数据类型(并不会序列化成byte[],目的是保留与其他程序交互数据的方式) ● 把Redis的Map封装成RedisMap类(key强制为...
为了保证数据的持久性,开发者可能使用 JSON 库序列化和反序列化笔记对象,或者选择 SQLite 数据库存储,利用 JDBC 进行数据库操作。同时,为了防止数据丢失,应用可能采用了事务处理,确保数据的完整性和一致性。 ...