17.7 序 列 化
序列化(serialization)是把一个对象的状态写入一个字节流的过程。当你想要把你的程序状态存到一个固定的存储区域例如文件时,它是很管用的。稍后一点时间,你就可以运用序列化过程存储这些对象。序列化也要执行远程方法调用(RMI)。RMI允许一台机器上的Java对象调用不同机器上的Java 对象方法。对象可以作为一个参数提供给那个远程方法。发送机序列化该对象并传送它。接受机反序列化它(关于RMI的更多内容请参看第24章)。假设一个被序列化的对象引用了其他对象,同样,其他对象又引用了更多的对象。这一系列的对象和它们的关系形成了一个顺序图表。在这个对象图表中也有循环引用。也就是说,对象X可以含有一个对象Y的引用,对象Y同样可以包含一个对象X的引用。对象同样可以包含它们自己的引用。对象序列化和反序列化的工具被设计出来并在这一假定条件下运行良好。如果你试图序列化一个对象图表中顶层的对象,所有的其他的引用对象都被循环的定位和序列化。同样,在反序列化过程中,所有的这些对象以及它们的引用都被正确的恢复。下面是支持序列化的接口和类的概述。
17.7.1 Serializable接口
只有一个实现Serializable接口的对象可以被序列化工具存储和恢复。Serializable接口没有定义任何成员。它只用来表示一个类可以被序列化。如果一个类可以序列化,它的所有子类都可以序列化。声明成transient的变量不被序列化工具存储。同样,static变量也不被存储。
17.7.2 Externalizable接口
Java的序列化和反序列化的工具被设计出来,所以很多存储和恢复对象状态的工作自动进行。然而,在某些情况下,程序员必须控制这些过程。例如,在需要使用压缩或加密技术时,Externalizable接口为这些情况而设计。Externalizable 接口定义了两个方法:
void readExternal(ObjectInput inStream)
throws IOException, ClassNotFoundException
void writeExternal(ObjectOutput outStream)
throws IOException
这些方法中,inStream是对象被读取的字节流,outStream是对象被写入的字节流。
17.7.3 ObjectOutput接口
ObjectOutput 继承DataOutput接口并且支持对象序列化。它定义的方法显示于表17-5中。特别注意writeObject( )方法,它被称为序列化一个对象。所有这些方法在出错情况下引发IOException 异常。
表17-5 ObjectOutput 定义的方法
方法 描述
void close( ) 关闭调用的流。关闭后的写操作会产生IOException异常
void flush( ) 定制输出状态以使每个缓冲器都被清除。也就是刷新输出缓冲
区
void write(byte buffer[ ]) 向调用的流写入一个字节数组
void write(byte buffer[ ], int offset,
int numBytes)
写入数组buffer中从buffer[offset]位置开始的numBytes个字节
长度区域内的数据
void write(int b) 向调用的流写入单个字节。写入的是b的低位字节