假设我们在序列化中,对一个对象进行多次序列化,反序列化是会是单个还是多个对象呢?先来看一个例子。
public class Pet implements Serializable {
private String name;
public Pet(String name) {
this.name = name;
}
public static void main(String[] args) throws IOException, ClassNotFoundException {
//构建序列化集合
ArrayList<Pet> pets = new ArrayList<>();
pets.add(new Pet("dog"));
pets.add(new Pet("cat"));
pets.add(new Pet("pig"));
System.out.println("------打印初始集合------");
System.out.println(pets);
//第一次构建输出流
ByteArrayOutputStream bout1 = new ByteArrayOutputStream();
ObjectOutputStream out1 = new ObjectOutputStream(bout1);
//第一次写入集合
out1.writeObject(pets);
System.out.println("------变更集合内容------");
//变更集合后第二次写入
pets.add(new Pet("sheep"));
System.out.println(pets);
out1.writeObject(pets);
ObjectInputStream in1 = new ObjectInputStream(new ByteArrayInputStream(bout1.toByteArray()));
ArrayList<Pet> pets1 = (ArrayList<Pet>) in1.readObject();
ArrayList<Pet> pets2 = (ArrayList<Pet>) in1.readObject();
System.out.println("------读取第一次写入的集合------");
System.out.println(pets1);
System.out.println("------读取第二次写入的集合------");
System.out.println(pets2);
ByteArrayOutputStream bout2 = new ByteArrayOutputStream();
ObjectOutputStream out2 = new ObjectOutputStream(bout2);
//第三次写入集合
out2.writeObject(pets);
//第四次写入集合
out2.writeObject(pets);
ObjectInputStream in2 = new ObjectInputStream(new ByteArrayInputStream(bout2.toByteArray()));
ArrayList<Pet> pets3 = (ArrayList<Pet>) in2.readObject();
ArrayList<Pet> pets4 = (ArrayList<Pet>) in2.readObject();
System.out.println("------读取第三次写入的集合------");
System.out.println(pets3);
System.out.println("------读取第四次写入的集合------");
System.out.println(pets4);
//关闭流
bout1.close();
bout2.close();
out1.close();
out2.close();
in1.close();
in2.close();
}
}
------打印初始集合------
[mtn.baymax.charpter18.Pet@1b6d3586, mtn.baymax.charpter18.Pet@4554617c, mtn.baymax.charpter18.Pet@74a14482]
------变更集合内容------
[mtn.baymax.charpter18.Pet@1b6d3586, mtn.baymax.charpter18.Pet@4554617c, mtn.baymax.charpter18.Pet@74a14482, mtn.baymax.charpter18.Pet@511d50c0]
------读取第一次写入的集合------
[mtn.baymax.charpter18.Pet@3feba861, mtn.baymax.charpter18.Pet@5b480cf9, mtn.baymax.charpter18.Pet@6f496d9f]
------读取第二次写入的集合------
[mtn.baymax.charpter18.Pet@3feba861, mtn.baymax.charpter18.Pet@5b480cf9, mtn.baymax.charpter18.Pet@6f496d9f]
------读取第三次写入的集合------
[mtn.baymax.charpter18.Pet@10f87f48, mtn.baymax.charpter18.Pet@b4c966a, mtn.baymax.charpter18.Pet@2f4d3709, mtn.baymax.charpter18.Pet@4e50df2e]
------读取第四次写入的集合------
[mtn.baymax.charpter18.Pet@10f87f48, mtn.baymax.charpter18.Pet@b4c966a, mtn.baymax.charpter18.Pet@2f4d3709, mtn.baymax.charpter18.Pet@4e50df2e]
从打印结果可以看出,在反序列化时,重复序列化出来的对象指向的都是同一个内存地址,证明反序列化时并不会复制相同的对象。
但这里值得注意的是,当我们第一次对 pets 序列化后,新增了第4个 Pet 类型,然后进行了第二次序列化,但第二个 pets 仍然指向了第一次序列化时的对象状态,仅仅保存了3个 Pet 类型,后续做出的修改并没有在之后的序列化中得到保存。
但重新创建了新的输出流 bout2 后,pets 的最新状态得以完整序列化。
故我们在使用序列化时:在一个输入流中,同一个对象只序列化一次,在一个输出流中,同一个对象只反序列化一次即可。
本次分享至此结束,希望本文对你有所帮助,若能点亮下方的点赞按钮,在下感激不尽,谢谢您的【精神支持】。
若有任何疑问,也欢迎与我交流,若存在不足之处,也欢迎各位指正!