首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 开发语言 > 编程 >

序列化到底是咋回事

2012-10-24 
序列化到底是怎么回事有感:花了7年多时间才感悟到什么样才是一个真正的程序员。“研究”了那么多“高深”的东西

序列化到底是怎么回事

有感:花了7年多时间才感悟到什么样才是一个真正的程序员。

“研究”了那么多“高深”的东西后才发现,原来“低级”的基础是那么重要。

面对基础,我又是那么无知。

?

所谓Java的序列化是指,Java对象(注意是对象、对象)可以被编码成字节码的形式(主要用于存储或传输),同时可以进行逆向的操作,“反”序列化成JVM中的对象。

?

当然,不是所有的Java对象都可以序列化:必须实现java.io.Serializable接口。

?

把对象序列化做什么用呢?

一方面,在分布的Java平台之意传递信息(Java对象);另外一方面,实现深度克隆一个Java对象。

?

估计80%的人也就理解到上述这些内容。

?

应用序列化的过程中,遇到关于序列化ID的问题,经过试验,得出一些心得,还写了博文:

http://sharajava.iteye.com/blog/102886

?

但实际上,现在才觉得可笑,Serializable的JavaDoc文档中就清楚地写明白着呢,如果早看,早就明白了。

?

其实,JavaDoc里一开始就表达到非常基础且重要的问题,自己却一直没考虑到过的:如果继承一个未实现序列化接口的类,子类实现序列化接口,那么父类的属性(成员变量)哪些被序列化,哪些不被序列化呢?

?

private void writeObject(java.io.ObjectOutputStream out) throws IOException private void readObject(java.io.ObjectInputStream in) throws IOException, ClassNotFoundException;

write方法是序列化的过程,read方法是反序列化的过程。参数中的Stream(对象流)就是过程中,类对象的实际内容。

也就是说,Java平台会在序列化和反序列化的过程中分别调用这两个方法。

当然,我们一般也只是需要“额外”做一些事情,核心的内容还是希望保持缺省的机制,我们就有可以调用两个参数输入、输出流的defaultWriteObject方法和defaultReadObject方法。?

?

上面这些内容,实际上用处还不是很大,至少我在开发过程中还没有什么需要一定要在这些机制上“做手脚”。

但在深入研究“单例”的问题时,遇到了下面这样的情况:单例

?

我们都知道,单例是希望在一定范围(一个类加载器)内,对于某类的实例仅有一个唯一的对象实例。

实现单例模式的方法很多,这里不多说,唯独如果希望实现单例的类实现了序列化接口,会出现什么样的问题?

我把单例的实例,在同一个应用范围内,序列化,再反序列化回来,不是又得到一个该类的对象?这样不就不是单例了吗?

?

不用担心,序列化机制还提供了两个方法:

?

 ANY-ACCESS-MODIFIER Object writeReplace() throws ObjectStreamException; ANY-ACCESS-MODIFIER Object readResolve() throws ObjectStreamException;
?

这两个方法可以理解为序列化和反序列化过程的入口和出口。writeReplace()返回的对象,就是要被序列化的对象,我们有机会在序列化前把这个对象给换成我们确定好的那个(如果不是“故意捣乱”,暂时没想到有什么用);而readResolve()方法就是在反序列化完成得到对象前,把这个对象给换成我们确定好的那个。

明白了吧?为了防止有人恶意通过序列化的机制破坏定义好的单例,我们就需要自己实现readResolve()方法,把单例定义的唯一实现在这个方法中返回。

?

对于序列化机制,我想基本有上述理解才能算得上理解吧?

其实真的没有什么特别的需要,只要仔细读一读JavaDoc即可,而我们大多数人(包括我自己)都往往忽略了这些所谓的基础。

?

?

?

?

热点排行