概念
- 序列化:Serialize,将Java对象存储到硬盘文件中,即将Java对象的状态保存下来的过程。
- 反序列化:DeSerialize,将硬盘的 数据恢复到内存当中,恢复成Java对象。
图解
详解
- 参与序列化的对象,必须实现Serializable 接口
- 通过源代码发现,Serializable接口仅是一个标志接口,接口中无其他代码。
- 那么它起到什么作用呢?起到标识的作用,标志的作用。Java虚拟机看到这个类实现了这个接口,可能会对这个类进行特殊待遇。Java虚拟机看到此标志,会为该类自动生成一个序列化版本号。
- Java语言中是采用什么机来区分类的
- 第一:首先通过类名进行对比,如果类名不一致,肯定不是同一个类。
- 第二:如果类名相同,依靠序列化版本号进行分别。
- 序列化版本号生成策略
- 第一种:自动生成序列化版本号,缺陷(一旦代码确定下来,不能进行后续的修改,因为只要修改,必然会重新编译,此时会产生新的序列化版本号,这样就会产生歧义)
- 第二种(建议使用):手动生成序列化版本号,给类提供一个固定不变的序列化版本号,这样即使后续代码修改了,序列化版本号也不会修改,Java虚拟机也会认为是同一个类。
private static final long serialVersionUID = 1L;
- idea快捷生成设置,然后在类名 alt+ enter 可以快捷生成了。
代码实现
public class Student implements Serializable {
// 序列化版本号
private static final long serialVersionUID = 1L;
private String name;
private int age;
public Student(String name, int age) {
this.name = name;
this.age = age;
}
public Student() {
}
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 "Student{" +
"name='" + name + '\'' +
", age=" + age +
'}';
}
}
// 序列化
public class SerializeTest {
public static void main(String[] args) throws IOException {
// 创建Java对象
Student student = new Student("李华", 22);
// 序列化
ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("student"));
// 序列化对象
oos.writeObject(student);
// 刷新
oos.flush();
// 关闭
oos.close();
}
}
// 反序列化
public class SerializeTest {
public static void main(String[] args) throws IOException, ClassNotFoundException {
ObjectInputStream ois = new ObjectInputStream(new FileInputStream("student"));
// 开始反序列化
Object obj = ois.readObject();
// 反序列化回来是一个学生对象,所以会调用其toString方法
System.out.println(obj);
// 关闭
ois.close();
}
}
- 注意:如果需要某个字段 不被序列化,需加transient(游离的)关键字
private transient int age;