序列化,对象输出流 ObjectOutputStream
反序列化,对象输入流:ObjectInputStream
前言
1、需要序列化和反序列化的类须实现接口 Serializable
,否则抛出异常NotSerializableException
;
2、若反序列化时类的 serialVersionUID
与序列化时不同,则抛出异常 InvalidClassException
;并且 local class incompatible: stream classdesc serialVersionUID = A, local class serialVersionUID = B
,其中值 A 是序列化时该字段的值,B 是反序列化时的值;如果没有特殊需求,就是用默认的 1L 就可以,这样可以确保代码一致时反序列化成功。那么随机生成的序列化 ID 有什么作用呢,有些时候,通过改变序列化 ID 可以用来限制某些用户的使用。
3、对于不需要序列化和反序列化的属性,可以使用关键字 transient
修饰;
实现
创建需要序列化和发序列化的类:
import java.io.Serializable;
// 实现接口 Serializable
public class Person implements Serializable {
private static final long serialVersionUID = 2L;
private String name;
private int age;
// 该字段可以不参与序列化和反序列化;也可以参与
transient private String gender;
public Person(String name, int age) {
this.name = name;
this.age = 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;
}
@Override
public String toString() {
return "Person{" +
"name='" + name + '\'' +
", age=" + age +
'}';
}
}
反序列化实现:
Person p1 = new Person("Alex", 28);
Person p2 = new Person("Sunny", 35);
Person p3 = new Person("Jane", 23);
Person p4 = new Person("Dany", 90);
ArrayList<Person> list = new ArrayList<>();
list.add(p1);
list.add(p2);
list.add(p3);
list.add(p4);
try {
ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("oos_demo3.txt"));
oos.writeObject(list);
oos.close();
} catch (IOException e) {
e.printStackTrace();
}
序列化:
try {
ObjectInputStream ois = new ObjectInputStream(new FileInputStream("oos_demo3.txt"));
ArrayList<Person> list = (ArrayList<Person>)ois.readObject();
for (Person person : list) {
System.out.println(person);
}
ois.close();
} catch (IOException e) {
e.printStackTrace();
} catch (ClassNotFoundException e) {
e.printStackTrace();
}