1.对象序列化的目标
将对象保存到磁盘中,或允许在网络中直接输出对象。
2.对象序列化的含义
对象的序列化是指将一个Java对象写入IO流中。
对象的反序列化是指从IO流中恢复该java对象。
3.对象序列化机制允许把内存中的java对象转化成与平台无关的二进制流,从而允许把这种二进制流持久地保存在磁盘上。通过网络将这种二进制流传输到另一个网络节点。其他程序一旦获得了这种二进制流,都可以将这种二进制流恢复成原来的java对象。对象序列化机制使得对象可以脱离程序的运行而独立存在。
4.如果需要让某个对象支持序列化机制,则必须让它的类是可序列化的。为了让某个类是可序列话的,该类必须实现如下两个接口之一:
Serializable
Externalizable
5
.使用Serializable来实现序列化非常简单,主要是让目标类实现Serializable标记接口即可,无须实现任何方法。
6.一旦某个类实现了Serializable接口,该类的对象就是可序列化的,通过两个步骤来序列化该对象:
(1)创建一个ObjectOutputStream,这个输出流是一个处理流。
ObjectOutputStream oos = new ObjectOutputStream(
new FileOutputStream("object.txt"));
(2)调用
ObjectOutputStream对象的writeObject()方法输出可序列化对象。
oos.writeObject(p);
7.从二进制数据中恢复java对象,则需要使用反序列化,步骤如下:
(1)创建一个ObjectInputStream输入流,这个输入流是一个处理流。
ObjectInputStream ois = new ObjectInputStream(
new FileInputStream("object.txt"));
(2)调用
ObjectInputStream对象的readObject()方法读取流中的对象,该方法返回一个Object类型的Java对象,如果程序知道该Java对象的类型,则可以将对象强制类型转换成其真实的类型。
Person p = (Person)ois.readObject();
8.实例
static public void writeObjectFunc(){
try {
ObjectOutputStream oos = new ObjectOutputStream(
new FileOutputStream("object.txt"));
Person p = new Person("Jack", 26);
oos.writeObject(p);
oos.close();
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
static public void readObjectFunc(){
try {
ObjectInputStream ois = new ObjectInputStream(
new FileInputStream("object.txt"));
try {
Person p = (Person)ois.readObject();
ois.close();
System.out.println(p);
} catch (ClassNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
public class Person implements Serializable{
private String name = null;
private int age = 0;
public Person(String name,int age){
this.name = name;
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public String toString(){
return getClass().getName()+"[name="+name+",age="+age+"]";
}
}
9.注意:
1.反序列化数据读取的仅仅是Java对象的,而不是Java类。因此采用反序列化恢复Java对象时,必须提供该Java对象所属类的class文件,否则将会引发ClassNotFoundException。
2.使用序列化机制向文件中写入多个java对象,使用反序列化恢复对象时,必须按照实际写入的顺序读取。
10.对象引用的序列化
当程序序列化一个对象时,如果该对象持有另一个对象的引用,为了在反序列化时可以正常恢复该对象,程序会顺带将引用对象也进行序列化,所以引用对象必须是可序列化的。
11.Java序列化机制的序列化算法
(1)所有保存到磁盘中的对象都有一个序列化编号。
(2)当程序试图序列化一个对象时,程序将先检查该对象是否已经被序列化过,只有该对象从未被序列化过,系统才会将该对象转换成字节序列并输出。
(3)如果某个对象已经序列化过,程序将只是直接输出一个序列化编号,而不是重新序列化该对象。
当多次调用writeObject()输出同一个对象时,只有第一次调用writeObject()方法时才会将对象转换成字节序列并输出。