Java—序列化流与反序列化流
一、序列化&反序列化
概念:
序列化:把Java对象转换为字节序列的过程。
反序列化:把字节序列恢复为Java对象的过程。
序列化接口
1. 当一个对象要能被序列化,这个对象所属的类必须实现Serializable接口。否则会发生异常NotSerializableException异常。
2. 同时当反序列化对象时,如果对象所属的class文件在序列化之后进行的修改,那么进行反序列化也会发生异常InvalidClassException。发生这个异常的原因如下:
① 该类的序列版本号与从流中读取的类描述符的版本号不匹配
② 该类包含未知数据类型
③ 该类没有可访问的无参数构造方法
3. Serializable标记接口。该接口给需要序列化的类,提供了一个序列版本号。serialVersionUID. 该版本号的目的在于验证序列化的对象和对应类是否版本匹配。
二、对象序列化流 ObjectOutputStream
可以使用 ObjectInputStream 读取(重构)对象。通过在流中使用文件可以实现对象的持久存储。
注:只能将支持 java.io.Serializable 接口的对象写入流中
public class ObjectStream01 {
public static void main(String[] args) throws IOException {
// 将一个对象存储到持久化(硬盘)的设备上
// 对象序列化
writeObj();
}
public static void writeObj() throws IOException {
FileOutputStream fos = new FileOutputStream("e:/objectStream.txt");
ObjectOutputStream oos = new ObjectOutputStream(fos);
// Person类必须序列化
oos.writeObject(new Person("wangkai", 21));
// 关闭资源
oos.close();
}
}
person类
public class Person implements Serializable {
//给类显示声明一个序列版本号
private static final long serialVersionUID = 2827802788464632315L;
private String name;
private int age;
public Person() {
super();
}
public Person(String name, int age) {
super();
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;
}
@Override
public String toString() {
return "Person [name=" + name + ", age=" + age + "]";
}
}
三、对象反序列化流 ObjectInputStream
public class ObjectStream02 {
public static void main(String[] args) throws IOException, ClassNotFoundException {
// 对象反序列化
readObj();
}
public static void readObj() throws IOException, ClassNotFoundException {
FileInputStream fis = new FileInputStream("e:/objectStream.txt");
ObjectInputStream ois = new ObjectInputStream(fis);
Person obj = (Person) ois.readObject();
System.out.println(obj.toString());
// 关闭资源
ois.close();
}
}