一.序列化
是什么:拆分对象,将java对象存储到硬盘中,将java对象的状态保存下来的过程
参与序列化的对象必须实现Serializable接口
二.反序列化
是什么:组装对象,将硬盘上的数据重新恢复到内存当中,恢复成java对象
参与反序列化的对象必须实现Serializable接口
三.序列化和反序列化的原理图
四.Serializable接口
public interface Serializable {
}
通过查看源代码发现这个接口中什么代码啊也没有 ,那他起到什么作用呢?
起到标识的作用,标志的作用,java虚拟机看到实现了这个接口,可能会对这个类进行特殊待遇,Serializable这个标志接口是给java虚拟机参考的,java虚拟机看到了这个接口之后。会为该类自动生成一个序列化版本号
五.实现序列化和反序列化的案例
首先准备一个实现了Serializable接口的实现类Student
序列化:
1.在测试类中创建Student对象
2.然后创建序列化的流对象,参数是一个包装流(OutputStream out)
3.调用序列化流的对象的writeObject()方法把Student写入到目标文件中
4.刷新流,关闭流
反序列化:
1.在测试类创建反序列化的流对象
2.调用反序列化的流对象的readObject()方法把目标文件保存的Student类读取到内存中,返回值是Object类型
3.关闭流
以下是具体代码
//准备一个实现了Serializable接口的类
public class Student implements Serializable {
int on;
String name;
public Student(int on, String name) {
this.on = on;
this.name = name;
}
@Override
public String toString() {
return "Student{" +
"on=" + on +
", name='" + name + '\'' +
'}';
}
}
public class 序列化的实现 {
public static void main(String[] args) throws Exception{
//创建学生对象
Student stu = new Student(24,"zhangsan");
//创建序列化对象
ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("C:\\Users\\24634\\Desktop\\起始文件夹\\student"));
//序列化对象
oos.writeObject(stu);
//刷新
oos.flush();
//关闭流
oos.close();
}
}
public class 反序列化的实现 {
public static void main(String[] args) throws Exception{
//创建一个反序列化的对象
ObjectInputStream ois = new ObjectInputStream(new FileInputStream("C:\\Users\\24634\\Desktop\\起始文件夹\\student"));
//开始反序列化
Object obj = ois.readObject();
System.out.println(obj.toString());//Student{on=24, name='zhangsan'}
//关闭流
ois.close();
}
}
六.给要实现序列化的对象设置或不设置序列化版本号的区别
不设置序列化版本号
如果不写序列化版本号,当我修改了类,必然会重新编译,此时会自动默认生成全新的序列化版本号,反序列化的时候发现与之前类的序列化版本号不一致就会出现InvalidClassException异常。
设置序列化版本号(建议)
如果手动提供了序列化版本号,当我修改了类,重新编译后序列化版本号不会变,java虚拟机会认为是同一个类,反序列化不会出现异常。