java对象序列化
所谓对象序列化就是将对象的状态转换成字节流,以后可以通过这些值再生成相同状态的对象。这个过程也可以通过网络实现,可以先在Windows机器上创建一个对象,对其序列化,然后通过网络发给一台Unix机器,然后在那里准确无误地重新"装配"。像RMI、Socket、JMS、EJB它们中的一种,彼此为什么能够传递Java对象,当然都是对象序列化机制的功劳。 java对象序列化机制一般来讲有两种用途: 1. 对象序列化可以实现分布式对象。主要应用例如:RMI要利用对象序列化运行远程主机上的服务,就像在本地机上运行对象时一样。 2. java对象序列化不仅保留一个对象的数据,而且递归保存对象引用的每个对象的数据。可以将整个对象层次写入字节流中,可以保存在文件中或在网络连接上传递。利用对象序列化可以进行对象的“深复制”,即复制对象本身及引用的对象本身。序列化一个对象可能得到整个对象序列。 java序列化比较简单,通常不需要编写保存和恢复对象状态的定制代码。实现java.io.Serializable接口的类对象可以转换成字节流或从字节流恢复,不需要在类中增加任何代码。只有极少数情况下才需要定制代码保存或恢复对象状态。这里要注意:不是每个类都可序列化,有些类是不能序列化的,例如涉及线程的类与特定JVM有非常复杂的关系。 序列化机制: 处理对象流: (序列化过程和反序列化过程) 1. // 序列化 today's date 到一个文件中. 2. FileOutputStream f = new FileOutputStream ("tmp" ); 3. ObjectOutputStream s = new ObjectOutputStream (f); 4. s.writeObject("Today" ); 5. s.writeObject(new Date ()); 6. s.flush(); 现在,让我们来了解ObjectInputStream这个类。它与ObjectOutputStream相似。它扩展DataInput接口。 ObjectInputStream中的方法镜像DataInputStream中读取Java基本数据类型的公开方法。readObject()方法从字节流中反序列化对象。每次调用readObject()方法都返回流中下一个Object。对象字节流并不传输类的字节码,而是包括类名及其签名。 readObject()收到对象时,JVM装入头中指定的类。如果找不到这个类,则readObject()抛出 ClassNotFoundException,如果需要传输对象数据和字节码,则可以用RMI框架。ObjectInputStream的其余方法用于定制反序列化过程。 1. //从文件中反序列化 string 对象和 date 对象 2. FileInputStream in = new FileInputStream ("tmp" ); 3. ObjectInputStream s = new ObjectInputStream (in); 4. String today = (String )s.readObject(); 5. Date date = (Date )s.readObject(); 定制序列化过程:
1. public class simpleSerializableClass implements Serializable { 2. String sToday="Today:" ; 3. transient Date dtToday=new Date (); 4. }
1. //重写writeObject()方法以便处理transient的成员。 2. public void writeObject(ObjectOutputStream outputStream) throws IOException { 3. outputStream.defaultWriteObject();//使定制的writeObject()方法可以 4. 利用自动序列化中内置的逻辑。 5. outputStream.writeObject(oSocket.getInetAddress()); 6. outputStream.writeInt(oSocket.getPort()); 7. } 8. //重写readObject()方法以便接收transient的成员。 9. private void readObject(ObjectInputStream inputStream) throws IOException ,ClassNotFoundException { 10. inputStream.defaultReadObject();//defaultReadObject()补充自动序列化 11. InetAddress oAddress=(InetAddress )inputStream.readObject(); 12. int iPort =inputStream.readInt(); 13. oSocket = new Socket (oAddress,iPort); 14. iID=getID(); 15. dtToday =new Date (); 16. } 完全定制序列化过程:
|