一、对象序列化
步骤:
1.创建出FileOutputStream
如果文件名对应文件不存在则会被自动创建出来
FileOutputStream fileStream = new FileOutputStream("MyFile.ser");
2.创建出ObjectOutputStream
ObjectOutputStream os = new ObjectOutputStream(fileStream);
3.写入对象
os.writeObject(characterOne);
os.writeObject(characterTwo);
os.writeObject(characterThree);
4.关闭ObjectOutputStream
os.close();
如果要让类能够被序列化,就让该类实现Serializable接口,此接口唯一目的就是声明有实现它的类可以被序列化,且该类的子类也自动可以序列化。
当对象被序列化时,被该对象引用的实例变量也会被序列化,且该对象中所有被引用的其他对象也会被序列化(该类以及该类中被引用的类都必须要实现Serializable接口)。
如果某某实例变量不能或不应该被序列化,就把它标记为transient(瞬时)的,即在实例化时以null返回。
二、对象解序列化
步骤:
1.创建FileIntputStream
如果文件名对应文件不存在则会抛出异常
FileIntputStream fileStream = new FileIntputStream("MyFile.ser");
2.创建ObjectIntputStream
ObjectIntputStream is = new ObjectIntputStream(fileStream);
3.读取对象
每次调用readObject()都会从stream中读出下一个对象,读取顺序与写入顺序相同,次数超过会抛出异常。
Object one = is.readObject();
Object two = is.readObject();
Object three = is.readObject();
4.转换对象类型
因为返回值时Object类型,因此必须要转换类型,转换为序列化时的类型。
Character ch1 = (Character)one; Character ch2 = (Character)two; Character ch3 = (Character)three;
5.关闭ObjectIntputStream
os.close();
具体过程:
1.将对象从stream中读出来;
2.java虚拟机通过存储的信息判断出对象的class类型;
3.Java虚拟机尝试寻找和加载对象的类,如果找不到或者无法加载该类,则会抛出异常;
4.新的对象会被配置在堆上,但构造函数不会执行;
5.如果该类在继承树上有一个不可序列化的祖先类,则从这个祖先类开始的构造函数都会执行;
6.对象的实例变量会被还原成序列化时的状态值,transient变量的对象引用赋null值,基本数据类型赋0、false等值。
要点:
1.对象必须实现序列化这个接口才能被序列化,如果父类实现了序列化接口,子类也就有实现;
2.静态变量不会被序列化,所有对象都是共享一份静态变量值;
3.读取顺序必须和写入顺序相同。