java序列化(一)

最近一直在看序列化方面的文章,本人大学刚毕业,尽管早就认识java,但一直都是略懂皮毛,现在工作了,才发现自己需要补充的东西太多。比如这个序列化,下面做个总结,总结最近看过的关于序列化的文章,这篇总结仅仅针对自己而言,有些觉得没必要叙述的就没有写上,只写了自认为欠缺的地方。其中杂糅了很多高手的总结,如有不当,还请多多包涵。以后如果看到好的文章,还是会进行编辑修改的。

1、问题的产生:
假如有两个类,分别是A和B,B类中含有一个指向A类对象的引用,现在我们对两个类进行实例化{ A a = new A(); B b = new B(); },这时在内存中实际上分配了两个空间,一个存储对象a,一个存储对象b,接下来我们想将它们写入到磁盘的一个文件中去,就在写入文件时出现了问题!因为对象b包含对对象a的引用,所以系统会自动的将a的数据复制一份到b中,这样的话当我们从文件中恢复对象时(也就是重新加载到内存中)时,内存分配了三个空间,而对象a同时在内存中存在两份,想一想后果吧,如果我想修改对象a的数据的话,那不是还要搜索它的每一份拷贝来达到对象数据的一致性,这不是我们所希望的!
以下序列化机制的解决方案:
1)保存到磁盘的所有对象都获得一个序列号(1, 2, 3等等)
2)当要保存一个对象时,先检查该对象是否被保存了。
3)如果以前保存过,只需写入"与已经保存的具有序列号x的对象相同"的标记,否则,保存该对象
通过以上的步骤序列化机制解决了对象引用的问题!

2、什么是序列化?
对象的寿命通常随着生成该对象的程序的终止而终止。有时候,可能需要将对象的状态保存下来,在需要时再将对象恢复。我们把对象的这种能记录自己的状态以便将来再生的能力。叫作对象的持续性(persistence)。对象通过写出描述自己状态的数值来记录自己 ,这个过程叫对象的串行化(即序列化,Serialization) 。串行化的主要任务是写出对象实例变量的数值。如果交量是另一对象的引用,则引用的对象也要串行化。这个过程是递归的,串行化可能要涉及一个复杂树结构的单行化,包括原有对象、对象的对象、对象的对象的对象等等。对象所有权的层次结构称为图表(graph)。

3、序列化干什么用?
简单说就是为了保存在内存中的各种对象的状态(也就是实例变量,不是方法),并且可以把保存的对象状态再读出来。虽然你可以用你自己的各种各样的方法来保存object states,但是Java给你提供一种应该比你自己好的保存对象状态的机制,那就是序列化。

4、什么情况下需要序列化?
1)当你想把的内存中的对象状态保存到一个文件中或者数据库中时候;
2)当你想用套接字在网络上传送对象的时候;
3)当你想通过RMI(远程方法调用)传输对象的时候;

5、哪些内容被序列化?
1)对象的类型;
2)对象属性的类型;
3)对象属性值;
即使类中有多少方法,都不会序列化这些方法。另外,被序列化的“属性”均是“非静态成员变量”,如果有transient关键字修饰,则不会被“序列化”(有static修饰的可以被序列化)。
关于transient:transient是Java语言的关键字,用来表示一个域不是该对象串行化的一部分。当一个对象被串行化的时候,transient型变量的值不包括在串行化的表示中。

补充:serialVersionUID作用:
序列化时为了保持版本的兼容性,即在版本升级时反序列化仍保持对象的唯一性。
如果你的类Serialized存到硬盘上面后,可是后来你却更改了类别的field(增加或减少或改名),当你Deserialize时,就会出现Exception的,这样就会造成不兼容性的问题。
但当serialVersionUID相同时,它就会将不一样的field以type的预设值Deserialize,这个可以避开不兼容性的问题。
关于serialVersionUID,推荐两篇博文:1)http://leeleo.iteye.com/blog/374978
2)http://www.iteye.com/topic/761540

你可能感兴趣的:(java,数据结构,Blog)