java序列化:java对象序列化

序列化过程就是对象写入字节流和从字节流中读取对象将对象状态转换成字节流的后可以用java.io包中各种字节流类将其保存到文件中管道到另线程中或通过网络连接将对象数据发送到另主机对象序列化功能非常简单、强大在RMI、Socket、JMS、EJB都有应用对象序列化问题在网络编程中并不是最激动人心课题但却相当重要具有许多实用意义对象序列化可以实现分布式对象主要应用例如:RMI要利用对象序列化运行远程主机上服务就像在本地机上运行对象时 java对象序列化不仅保留个对象数据而且递归保存对象引用每个对象数据可以将整个对象层次写入字节流中可以保存在文件中或在网络连接上传递利用对象序列化可以进行对象“深复制”即复制对象本身及引用对象本身序列化个对象可能得到整个对象序列
从上面叙述中我们知道了对象序列化是java编程中必备武器那么让我们从基础开始好好学习下它机制和使用方法

java序列化比较简单通常不需要编写保存和恢复对象状态定制代码实现java.io.Serializable接口类对象可以转换成字节流或从字节流恢复不需要在类中增加任何代码只有极少数情况下才需要定制代码保存或恢复对象状态这里要注意:不是每个类都可序列化有些类是不能序列化例如涉及线程类和特定JVM有非常复杂关系

序列化机制:
序列化分为两大部分:序列化反序列化序列化是这个过程部分将数据分解成字节流以便存储在文件中或在网络上传输反序列化就是打开字节流并重构对象对象序列化不仅要将基本数据类型转换成字节表示有时还要恢复数据恢复数据要求有恢复数据对象例子ObjectOutputStream中序列化过程和字节流连接包括对象类型和版本信息反序列化时JVM用头信息生成对象例子然后将对象字节流中数据复制到对象数据成员中下面我们分两大部分来阐述:


处理对象流:(序列化过程和反序列化过程)

java.io包有两个序列化对象ObjectOutputStream负责将对象写入字节流ObjectInputStream从字节流重构对象
我们先了解ObjectOutputStream类吧ObjectOutputStream类扩展DataOutput接口
writeObject思路方法是最重要思路方法用于对象序列化如果对象包含其他对象引用则writeObject思路方法递归序列化这些对象每个ObjectOutputStream维护序列化对象引用表防止发送同对象多个拷贝(这点很重要)由于writeObject可以序列化整组交叉引用对象因此同ObjectOutputStream例子可能不小心被请求序列化同对象这时进行反引用序列化而不是再次写入对象字节流
下面让我们从例子中来了解ObjectOutputStream这个类吧

// 序列化 today's date 到个文件中. FileOutputStream f = FileOutputStream("tmp"); ObjectOutputStream s = ObjectOutputStream(f); s.writeObject("Today"); s.writeObject( Date); s.flush;

现在让我们来了解ObjectInputStream这个类它和ObjectOutputStream相似它扩展DataInput接口ObjectInputStream中思路方法镜像DataInputStream中读取Java基本数据类型公开思路方法readObject思路方法从字节流中反序列化对象每次readObject思路方法都返回流中下个Object对象字节流并不传输类字节码而是包括类名及其签名readObject收到对象时JVM装入头中指定如果找不到这个类则readObject抛出ClassNotFoundException,如果需要传输对象数据和字节码则可以用RMI框架ObjectInputStream其余思路方法用于定制反序列化过程
例子如下:

//从文件中反序列化 对象和 date 对象 FileInputStream in = FileInputStream("tmp"); ObjectInputStream s = ObjectInputStream(in); String today = (String)s.readObject; Date date = (Date)s.readObject;


定制序列化过程:

序列化通常可以自动完成但有时可能要对这个过程进行控制java可以将类声明为serializable但仍可手工控制声明为或transient数据成员
例子:个非常简单序列化类

public simpleSerializableClass implements Serializable{ String sToday="Today:"; transient Date dtToday= Date; }

序列化时所有数据成员应可序列化除了声明为transient或成员将变量声明为transient告诉JVM我们会负责将变元序列化将数据成员声明为transient后序列化过程就无法将其加进对象字节流中没有从transient数据成员发送数据后面数据反序列化时要重建数据成员(它是类定义部分)但不包含任何数据这个数据成员不向流中写入任何数据记住对象流不序列化或transient我们类要用writeObject和readObject思路方法以处理这些数据成员使用writeObject和readObject思路方法时还要注意按写入顺序读取这些数据成员
有关如何使用定制序列化部分代码如下:

//重写writeObject思路方法以便处理transient成员 public void writeObject(ObjectOutputStream outputStream) throws IOException{ outputStream.defaultWriteObject;//使定制writeObject思路方法可以 利用自动序列化中内置逻辑 outputStream.writeObject(oSocket.getInetAddress); outputStream.writeInt(oSocket.getPort); } //重写readObject思路方法以便接收transient成员 private void readObject(ObjectInputStream inputStream) throws IOException,ClassNotFoundException{ inputStream.defau
Tags:  什么是序列化 序列化 对象序列化 java序列化

延伸阅读

最新评论

发表评论