所谓对象序列化就是将对象的状态转换成字节流,以后可以通过这些值再生成相同状态的对象 。这个过程也可以通过网络实现 , 可以先在Windows机器上创建一个对象,对其序列化,然后通过网络发给一台Unix机器,然后在那里准确无误地重新“装配” 。像RMI、Socket、JMS、EJB它们中的一种,彼此为什么能够传递Java对象 , 当然都是对象序列化机制的功劳 。
Java对象序列化机制一般来讲有两种用途:
Java的JavaBeans: Bean的状态信息通常是在设计时配置的,Bean的状态信息必须被存起来,以便当程序运行时能恢复这些状态信息 , 这需要将对象的状态保存到文件中,而后能够通过读入对象状态来重新构造对象 , 恢复程序状态 。
RMI允许象在本机上一样操作远程机器上的对象;或使用套接字在网络上传送对象的程序来说 , 这些都是需要实现serializaiton机制的 。
我们通过让类实现Java.io.Serializable 接口可以将类序列化 。这个接口是一个制造者(marker)接口 。也就是说 , 对于要实现它的类来说,该接口不需要实现任何方法 。它主要用来通知Java虚拟机(JVM),需要将一个对象序列化 。
对于这个 , 有几点我们需要明确:
并非所有类都可以序列化,在cmd下,我们输入serialver Java.net.Socket , 可以得到socket是否可序列化的信息,实际上socket是不可序列化的 。
Java有很多基础类已经实现了serializable接口,比如string,vector等 。但是比如hashtable就没有实现serializable接口 。
将对象读出或者写入流的主要类有两个: ObjectOutputStream与ObjectInputStream .ObjectOutputStream 提供用来将对象写入输出流的writeObject方法,ObjectInputStream提供从输入流中读出对象的readObject方法 。使用这些方法的对象必须已经被序列化的 。也就是说 , 必须已经实现 Serializable接口 。如果你想writeobject一个hashtable对象,那么,会得到一个异常 。
序列化的过程就是对象写入字节流和从字节流中读取对象 。将对象状态转换成字节流之后 , 可以用Java.io包中的各种字节流类将其保存到文件中,管道到另一线程中或通过网络连接将对象数据发送到另一主机 。对象序列化功能非常简单、强大 , 在RMI、Socket、JMS、EJB都有应用 。对象序列化问题在网络编程中并不是最激动人心的课题,但却相当重要,具有许多实用意义 。
对象序列化可以实现分布式对象 。主要应用例如:RMI要利用对象序列化运行远程主机上的服务,就像在本地机上运行对象时一样 。
Java对象序列化不仅保留一个对象的数据,而且递归保存对象引用的每个对象的数据 。可以将整个对象层次写入字节流中 , 可以保存在文件中或在网络连接上传递 。利用对象序列化可以进行对象的“深复制”,即复制对象本身及引用的对象本身 。序列化一个对象可能得到整个对象序列 。
Java序列化比较简单 , 通常不需要编写保存和恢复对象状态的定制代码 。实现Java.io.Serializable接口的类对象可以转换成字节流或从字节流恢复,不需要在类中增加任何代码 。只有极少数情况下才需要定制代码保存或恢复对象状态 。这里要注意:不是每个类都可序列化 , 有些类是不能序列化的,例如涉及线程的类与特定JVM有非常复杂的关系 。
序列化机制:
序列化分为两大部分:序列化 和反序列化。序列化是这个过程的第一部分 , 将数据分解成字节流,以便存储在文件中或在网络上传输 。反序列化就是打开字节流并重构对象 。对象序列化不仅要将基本数据类型转换成字节表示 , 有时还要恢复数据 。恢复数据要求有恢复数据的对象实例 。ObjectOutputStream中的序列化过程与字节流连接,包括对象类型和版本信息 。反序列化时,JVM用头信息生成对象实例,然后将对象字节流中的数据复制到对象数据成员中 。下面我们分两大部分来阐述:
处理对象流:
?。ㄐ蛄谢毯头葱蛄谢蹋?
Java.io包有两个序列化对象的类 。ObjectOutputStream负责将对象写入字节流,ObjectInputStream从字节流重构对象 。
我们先了解ObjectOutputStream类吧 。ObjectOutputStream类扩展DataOutput接口 。
writeObject() 方法是最重要的方法,用于对象序列化 。如果对象包含其他对象的引用,则writeObject()方法递归序列化这些对象 。每个 ObjectOutputStream维护序列化的对象引用表,防止发送同一对象的多个拷贝 。(这点很重要)由于writeObject()可以序列化整组交叉引用的对象,因此同一ObjectOutputStream实例可能不小心被请求序列化同一对象 。这时,进行反引用序列化 , 而不是再次写入对象字节流 。
【Java对象序列化的使用】