今天我们主要来讲解一下对象序列化,首先我们需要知道什么是对象序列化,所谓的对象序列化就是将一个对象转换为二进制流,如果一个类的对象要想实现序列化,则该对象所在的类必须实现Serializable接口,在此接口中没有任何的方法,此接口只是作为一个标识,表示本类的对象具备了序列化的能力。
序列化的思想是“冻结”对象状态,传输对象状态(写到磁盘、通过网络传输等等),然后“解冻”状态,重新获得可用的Java对象,所有这些事情的发生有点像魔术,这要归功于ObjectInputStream/ObjectOutputStream类,完全保真的元数据以及程序员愿意用Serializable标识接口标记他们的类,从而“参与”这个过程。
序列化分为两大部分:序列化和反序列化。序列化是这个过程的第一部分,将数据分解成字节流,以便存储在文件中或在网络上传输。反序列化就是打开字节流并重构对象。对象序列化不仅要将基本数据类型转换成字节表示,有时还要恢复数据。恢复数据要求有恢复数据的对象实例,如果某个类能够被序列化,其子类也可以被序列化。声明为static和transient类型的成员数据不能被序列化。因此static代表类的状态,transient代表对象的临时数据。
对象序列化在一下场景使用比较合适:
a)当你想把的内存中的对象状态保存到一个文件中或者数据库中时候;
b)当你想用套接字在网络上传送对象的时候;
c)当你想通过RMI(Remote Method Invocation 远程方法调用)传输对象的时候;
如果要想实现对象的序列化,则还要依靠ObjectOutputStream类和ObjectInputStream类,前者属于序列化操作,而或者属于反序列化操作。
package com.iflytek.io03;
import java.io.Serializable;
/**
* @author xudongwang 2012-1-8
*
* Email:xdwangiflytek@gmail.com
*/
public class Person implements Serializable {
private String name;
private int age;
public Person(String name, int age) {
super();
this.name = name;
this.age = age;
}
public String toString() {
return "姓名:" + this.name + ",年龄:" + this.age;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
下面通过ObjectOutputStream完成序列化操作:
package com.iflytek.io03;
import java.io.File;
import java.io.FileOutputStream;
import java.io.ObjectOutputStream;
/**
* @author xudongwang 2012-1-8
*
* Email:xdwangiflytek@gmail.com
*/
public class ObjectOutputStreamDemo {
public static void main(String args[]) throws Exception {
File file = new File("d:" + File.separator + "demo.txt");
ObjectOutputStream oos = null;
oos = new ObjectOutputStream(new FileOutputStream(file));
Person per = new Person("王旭东", 21);
oos.writeObject(per);
oos.close();
}
}
对象被实例化之后,就可以通过ObjectInputStream进行反序列化的操作
package com.iflytek.io03;
import java.io.File;
import java.io.FileInputStream;
import java.io.ObjectInputStream;
/**
* @author xudongwang 2012-1-8
*
* Email:xdwangiflytek@gmail.com
*/
public class ObjectInputStreamDemo {
public static void main(String args[]) throws Exception {
File file = new File("d:" + File.separator + "demo.txt");
ObjectInputStream ois = null;
ois = new ObjectInputStream(new FileInputStream(file));
Object obj = ois.readObject();
Person per = (Person) obj;
System.out.println(per);
}
}
以上操作实际上是整个对象进行的序列化操作,如果现在假设类中的某个属性不希望被序列化的话,则使用transient关键字进行声明;
private transient String name;
由上面可知可以对一个对象序列化,那么因为Object可以接受任意的引用数据类型,所以也可以同时对多个对象一起进行序列化操作,包括数组;
package com.iflytek.io03;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
/**
* @author xudongwang 2012-1-8
*
* Email:xdwangiflytek@gmail.com
*/
public class SerializableDemo {
public static void main(String args[]) throws Exception {
Person per[] = { new Person("张三", 30), new Person("李四", 40),new Person("王五", 50) };
serializable(per);
Person p[] = (Person[]) delSerializable();
print(p);
}
public static void serializable(Object obj) throws Exception {
File file = new File("d:" + File.separator + "demo.txt");
ObjectOutputStream oos = null;
oos = new ObjectOutputStream(new FileOutputStream(file));
oos.writeObject(obj);
oos.close();
}
public static Object delSerializable() throws Exception {
Object temp = null;
File file = new File("d:" + File.separator + "demo.txt");
ObjectInputStream ois = null;
ois = new ObjectInputStream(new FileInputStream(file));
temp = ois.readObject();
return temp;
}
public static void print(Person per[]) {
for (Person p : per) {
System.out.println(p);
}
}
}