JavaSE笔记15.11-IO流-序列化流和反序列化流
一. 概述
ObjectOutputStream
序列化流,以流的方式将对象以文件的形式保存到本地硬盘中
ObjectInputStream
反序列化流,将之前使用ObjectOutputStream序列化的原始数据恢复为对象,以流的方式读取对象
二. 方法
1. 构造方法
//创建一个从指定的InputStream读取的ObjectInputStream
ObjectInputStream(InputStream in);
//创建一个写入指定的OutputStream的ObjectOutputStream
ObjectOutputStream(OutputStream out);
2. 特有成员方法
//从ObjectInputStream读取一个对象
Object readObject();
//将指定对象写入ObjectOutputStream
void writeObject(Object obj);
3. 注意事项
被操作的对象需要实现Serializable(标记接口)
三. Serializable接口
Java类通过实现Serializable接口和定义serialVersionUID常量以启用其序列化功能,未实现此接口的类型将无法使其任何状态序列化或反序列化。
1. Serializable接口
没有任何方法或字段,只是作为一个标识接口存在。
2. serialVersionUID常量
- JVM在序列化对象的时候,用这个常量表示序列化对象所属的类的类ID
- 在反序列化时,反序列化对象的serialVersionUID能匹配上程序里面的类的serialVersionUID时,就判断这个反序列化的对象就是这个类生成的,因此允许反序列化
- 可序列化类可以通过声明名为serialVersionUID的字段显式声明其自己的serialVersionUID
如:static final long serialVersionUID=42L; - 如果可序列化类未显式声明serialVersionUID,则序列化运行时将基于该类的各个方面计算该类的默认serialVersionUID值
- serialVersionUID字段必须是静态的、最终的,类型是long
四. 例子
import java.io.*;
//实现Serializable接口,可序列化类
class Person implements Serializable{
//可序列化类显式声明serialVersionUID
//如果没有显式声明,序列化运行时将基于该类的各个方面计算该类的默认serialVersionUID值
public static final long serialVersionUID=42L;
String name;
int age;
Person(String name,int age){
this.name=name;
this.age=age;
}
public String toString(){
return name+":"+age;
}
}
public class ObjectStreamDemo {
public static void main(String[] args) {
try {
writeObj();
readObj();
} catch (Exception e) {
e.printStackTrace();
}
}
//序列化流,以流的方式将对象以文件的形式保存到本地硬盘中
private static void writeObj() throws IOException {
ObjectOutputStream oos=new ObjectOutputStream(new FileOutputStream("obj.txt"));
oos.writeObject(new Person("zhangsan",30));
oos.writeObject(new Person("lisi",22));
oos.close();
}
//反序列化流,将被序列化的原始数据恢复为对象
private static void readObj() throws Exception {
ObjectInputStream ois=new ObjectInputStream(new FileInputStream("obj.txt"));
Person p1=(Person)ois.readObject();
Person p2=(Person)ois.readObject();
System.out.println(p1);
System.out.println(p2);
ois.close();
}
}