Flyingis

Talking and thinking freely !
Flying in the world of GIS !
随笔 - 156, 文章 - 16, 评论 - 589, 引用 - 0
数据加载中……

Java I/O中的对象序列化

作者:Flyingis

      Java对象序列化将那些实现了Serializable接口的对象转换成一个字节序列,并能够以后将这个字节序列完全恢复为原来的对象。利用对象的序列化,可以实现轻量级持久性,这意味着一个对象的生存周期并不取决于程序是否正在执行,它可以生存于程序的调用之间。通过将一个序列化对象写入磁盘,然后在重新调用程序时恢复该对象,就能够实现持久性的效果。JDOHibernate等中间件为我们提供了更规范、完善的持久化机制,这里所述只是最基本的基于文件I/O的持久化。

对象序列化主要是为了支持两种主要的特性,一是Java远程方法调用(RMI),另外一个是序列化Java Beans

1.        实现了Serializable接口的对象的序列化

要序列化一个对象,首先要创建OutputStream对象,然后将其封装在一个ObjectOutputStream对象内。此时,调用writeObject()方法将对象序列化并发送给OutputStream。在反序列化时,需要将一个InputStream封装在ObjectInputStream内,然后调用readObject(),得到的结果是一个Object对象,需要进行转型得到最后所需的对象。需要注意的是,在对一个Serializable对象进行反序列化的过程中,没有调用任何构造器,包括缺省的构造器,整个对象都是通过从InputStream中取得数据恢复过来的。对象序列化是面向字节的,因此采用InputStreamOutputStream层次结构。

2.        实现了Externalizable接口的对象的序列化

Externalizable接口继承了Serializable接口,同时添加了writeExternal()readExternal(),它们在序列化和反序列化过程中会被自动调用。出于安全的考虑,可以将需要序列化的对象在上述方法中显式处理,否则不用在上述两个方法内考虑。注意,对于实现了Serializable接口的对象,对象完全以它存储的二进制位为基础来构造,不调用构造器。而对于一个Externalizable对象,所有普通的缺省构造器都会被调用,然后调用readExternal()

3.        transient关键字

在某些情况下,有些特定的子对象不希望Java序列化机制自动保存与恢复,即使对象中的这些信息是private的,经过序列化处理,就可以通过读取文件或者拦截网络传输的方式来访问到它。实现了Externalizable接口的对象的writeExternal()方法可以对需要的对象进行显式的序列化,但是如果我们操作的是一个实现了Serializable接口的对象,就只能用transient关键字逐个字段的关闭序列化,只需要在字段定义前加上该关键字即可。

4.        实现了Serializable接口的同时,提供两个方法

private void writeObject(ObjectOutputStream stream) throws IOException

private void readObject(ObjectInputStream stream)

throws IOException, ClassNotFoundException

这种方法使用起来比较混乱,仅仅提供了这样的一种功能,绝大多数情况下,使用前面三种方法就能满足需求。

posted on 2006-01-08 13:13 Flyingis 阅读(2624) 评论(5)  编辑  收藏 所属分类: JavaSE

评论

# re: Java I/O中的对象序列化  回复  更多评论   

第四种Serializable才是提倡的做法。建议读读Effective Java中关于Serializable那章
2006-01-12 10:26 | riverbuilding

# re: Java I/O中的对象序列化  回复  更多评论   

第四种理解起来有些晦涩,有时间我会进行考证。
2006-01-12 10:40 | Flyingis

# re: Java I/O中的对象序列化  回复  更多评论   

>在对一个Serializable对象进行反序列化的过程中,没有调用任何构造器,包括缺省的构造器

抱歉又要挑刺了,Serializable对象在反序列化时,是要调用缺省构造函数的,否则 JVM 怎么知道多了一个对象实例?
2006-01-13 13:53 | 笨笨

# re: Java I/O中的对象序列化  回复  更多评论   

@ 笨笨
每一次复习都会带来许多新的体会,也会存在知识的盲点,本来就是学习,欢迎你随时挑刺。
关于Serializable对象进行反序列化的过程中是否调用构造器,我在网上搜索了一下,没找到确切的答案。这句话源自《Thinking in Java 3rd》。
2006-01-14 12:45 | Flyingis

# re: Java I/O中的对象序列化  回复  更多评论   

没有最后一种的话,以前java不能实现真正的singleton pattern的。
最后一种很有用。
2006-01-22 13:50 | 程序员

只有注册用户登录后才能发表评论。


网站导航: