IO流之序列化
把内存中的对象永久保存到硬盘的过程称为对象序列化,也叫做持久化。
把硬盘持久化的内存恢复的内存的过程称为对象反序列化。
Serializable
对象序列化(持久化),一定要在对象类中实现Serializable接口,不需要实现方法。注意:未实现该接口,则对象将无法序列化或反序列化,并且抛出异常。
使用Serializable接口没有方法或者字段,仅用于标识可序列化的语义。
1 public class Student implements Serializable { 2 private int id; 3 private String name; 4 private int age; 5 }
序列化对象
ObjectOutputStream继承于OutputSteam,专门用于把对象序列化到本地。提供了
writeXXX():用于写入各种类型的数据。
writeObject():用于写入一个对象。
1 public static void main(String[] args) throws IOException { 2 Student student=new Student(1, "小明", 30); 3 4 File file=new File("d:\\sxt2019\\f.txt"); 5 FileOutputStream fileOutputStream=new FileOutputStream(file); 6 ObjectOutputStream objectOutputStream=new ObjectOutputStream(fileOutputStream); 7 8 objectOutputStream.writeObject(student); 9 fileOutputStream.close(); 10 objectOutputStream.close(); 11 }
反序列化对象
ObjectInputStream 继承于InputStream,专门把本地文件中序列化(持久化)的内容反序列化到内存中。提供有
readXXX():读取某种类型的数据内容。
readIObject():读取一个已经序列化的对象到内存中。
1 public static void main(String[] args) throws IOException, ClassNotFoundException { 2 File file=new File("d:\\sxt2019\\f.txt"); 3 FileInputStream fileInputStream=new FileInputStream(file); 4 ObjectInputStream objectInputStream=new ObjectInputStream(fileInputStream); 5 6 Student student=(Student) objectInputStream.readObject(); 7 System.out.println(student); 8 }
序列化版本问题
当序列化完成后,后期修改序列化的类,此时若再反序列化,会报错
Exception in thread "main" java.io.InvalidClassException: cn.sxt05.serializable.Student; local class incompatible: stream classdesc serialVersionUID = -6288733824962181189, local class serialVersionUID = 1690603786167234505
at java.io.ObjectStreamClass.initNonProxy(ObjectStreamClass.java:687)
at java.io.ObjectInputStream.readNonProxyDesc(ObjectInputStream.java:1876)
at java.io.ObjectInputStream.readClassDesc(ObjectInputStream.java:1745)
at java.io.ObjectInputStream.readOrdinaryObject(ObjectInputStream.java:2033)
at java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1567)
at java.io.ObjectInputStream.readObject(ObjectInputStream.java:427)
at cn.sxt05.serializable.Test02.main(Test02.java:16)
报错原因:因为序列化完成后,系统会生产一个序列化版本号serialVersionUID,并且连同数据一起保存到内存中。若后期修改了类的内容,序列化版本号也会随之修改更新,所以反序列化该类的时候,因为两个版本号不一致,导致报错。
修改方法:在序列化前,把版本号serialVersionUID写死即可。
有两种方式:
default serial version ID 生成默认的serial version ID 一般值都是1L。
generated serial version ID 根据当前类的属性、方法生成一个唯一ID。
transient
开发过程中,如果想忽略某些字段不让其系列化,可以使用transient修饰。