对象序列化概念
对象是存在内存中的,有时候我们需要将对象保存到硬盘上,又有时我们需要将对象传输到另一台计算机上等等这样的操作。这时我们需要将对象转换为一个字节序列,而这个过程就称为对象序列化。相反,我们有这样一个字节序列需要将其转换为对应的对象,这个过程就称为对象的反序列化。
对象------------>对象序列化------------->字节序列
对象<------------对象反序列化<--------------字节序列
使用OOS实现对象序列化
ObjectOutputStream是用来对对象进行序列化的输出流。
其实现对象序列化的方法为:
-void writeObject(Object o)
该方法可以将给定的对象转换为一个字节序列后写出。
使用OIS实现对象反序列化
ObjectInputStream是用来对对象进行反序列化的输入流。
其实现对象反序列化的方法为:
--Object readObject()
该方法可以从流中读取字节并转换为对应的对象。
Serializable接口
ObjectOutputStream在对对象进行序列化时有一个要求,就是需要序列化的对象所属的类必须实现Serializable接口
实现该接口不需要重写任何方法,其只是作为可序列化的标志。
通过实现该接口的类需要提供一个常量serialVersionUID,表明该类的版本。若不显示的声明,在对象序列化时也会根据当前类的各个方面计算该类的默认serialVersionUID,但不同平台编译器实现有所不同,所有若想跨平台,都应显示的声明版本号。
如果声明的类的对象序列化存到硬盘上面,之后随着需求的变化更改了类的属性(增加或减少或改名),那么当反序列化时,就会出现InvalidClassException,这样就会造成不兼容的问题。
但当serialVersionUID相同时,它就会将不一样的field以type的预设值反序列化,可避开不兼容问题。
transient关键字
对象在序列化后得到的字节序列往往比较大,有时我们在对一个对象进行序列化时可以忽略某些不必要的属性,从而对序列化后得到的字节序列"瘦身"
实现Emp的序列化
FileOutputStream fos=new FileOutputStream("emp.obj");
ObjectOutputStream oos=new ObjectOutputStream(fos);
Emp emp=new Emp("张三",15,"男",4000);
oos.writeObject(emp);
System.out.println("序列化完毕");
oos.close();
实现Emp的反序列化
FileInputStream fis=new FileInputStream("emp.obj");
ObjectInputStream ois=new ObjectInputStream(fis);
Emp emp=(Emp)ois.readObject();
System.out.println("反序列化完毕");
System.out.println(emp);
ois.close();