人和电脑在很多方面都是十分相似的,大脑可以看成电脑主机,五官/身体等表面器官就是显示器、鼠标等外设。这篇文章就是想把计算机跟人做类比YY一下序列化和反序列化的机制、用途。
如果你是初学者,心里肯定会问究竟什么是序列化/反序列化?其实我现在正在序列化而你正在反序列化:我在写这篇博客的时候就是把大脑中的想法和思想经过梳理写成连续的文字,这就是序列化,而你在读这篇博客的时候把这些整理过的文字读进大脑形成你自己的思想,这个过程就是反序列化。 我们可以把大脑中的想法通过文字或声音传递,这样有“共同语言”的人就能将这些文字,声音"读"进大脑形成自己的思想,这就是 人与人之间“沟通、交流”的过程;为了防止记忆丢失我们通常会把自己的一些想法、知识以文字形式或声音进行“保存”。 计算机中序列化的定义是:把对象转换成数据流以便在网络上进行传输,或者将对象持久的存储在某个地方的过程;相反,反序列化是接收数据流转换成对应的对象或从持久化存储读取数据转换成对象的过程。简单来说序列化就是用来做"有意义"的存储或通信的。在Java中我们可以把一个对象序列化到网络流,文件流,也可以序列化到字节数组等,然后可以从网络流、文件流和字节数组等反序列化生成相应的对象。
上面已经提到序列化、反序列化主要用于对象的持久化存储和远程通信。尤其在分布式系统中,应用十分广泛。
下面对Java默认实现的序列化机制做一个由浅入深的介绍。
a.首先是序列化机制的目标,下面是官方说明:
1.简单且易于扩展;
2.序列化形式能够保证Java对象类型信息和安全属性信息不丢失;
3.方便扩展支持marshalling和unmarshalling,这是实现远程对象的基础;
4.易于扩展,能方便实现Java对象的持久化;
5.针对不同类的对象提供可定制的持久化方式;
6.允许对象定制自己的外部表示形式;
b. java默认提供的序列化机制:
1.序列化的基本步骤:
FileOutputStream fos = new FileOutputStream(outputFile)
1:ObjectOutputStream oos = new ObjectOutputStream(fos);
2:oos.writeObject(object);
3:oos.close();
第一步是创建一个对象输出流oos,可以把对象序列化到文件、字节数组等,在构造oos时赋予不同类型的流参数即可。
在ObjectOutputStream的JDK实现中可以看出,构造oos对象时有安全管理器的校验、设置流格式(包括设置流的头信息:两个MagicNumber)。
第二步就是写入需要序列化的对象,这一步也是最为复杂的,包含了序列化机制的细节信息。
第三步关闭流。
第一步创建对象输出流的时候,其实会初始化两个Table:HandleTable和ReplaceTable,HandleTable主要是为了防止相同对象数据的重复写入而设计。其中保存了原始对象到标志此对象index的映射,这样碰到重复的对象时写入的实际上是这个index而非原始对象数据。还可以对原始序列化对象进行替换,ReplaceTable用来保存被替换对象的信息。
序列化机制里面有很多细节值得去挖掘:
比如:1.Java中的引用到底是什么,而序列化对象的时候如何消除重复对象的保存。
2.对于cycle reference的情况又是如何处理的。
后面将做更加详细的分析。