深度克隆:ObjectInputStream、ObjectOutputStream和ByteArrayOutputStream

时间:2022-05-15 08:02:05

下面一段深度克隆的源码,不甚理解,查查记录下来

 bout = new ByteArrayOutputStream();      //定义一个字节数组输出流
ObjectOutputStream oos = null; //对象输出流
ObjectInputStream ois = null;

oos = new ObjectOutputStream(bout);
oos.writeObject(oldValue); //将指定的对象写入字节数组输出,进行序列化
ByteArrayInputStream bin = new ByteArrayInputStream(bout.toByteArray());
ois = new ObjectInputStream(bin); //执行反序列化,从流中读取对象
newValue = (Serializable) ois.readObject();
ByteArrayOutputStream类实现了一个输出流,其中的数据被写入一个 byte 数组。缓冲区会随着数据的不断写入而自动增长。可使用 toByteArray() 和 toString() 获取数据,它的大小是该输出流中已存入的有效数据的当前大小。例如:
    int a = 0,b = 1,c = 2;    ByteArrayOutputStream bout = new ByteArrayOutputStream();     bout.write(a);     bout.write(b);     bout.write(c);     byte[] buff = bout.toByteArray();     for (int i = 0; i < buff.length; i++)         System.out.println(buff[i]);
输出的结果为:0、1、2。

java这种面向对象的语言在编程的时候数据大都存储在对象中,有时需要将内存中的所有对象写到文件中去,然后在适当的时候将文件中的对象还原至内存中,上边代码中出现的ObjectInputStream与ObjectOutputStream这两个类就可以完成这个任务。

序列化是指将对象的状态信息转换为可以存储或传输的形式的过程。在序列化期间,对象将其当前状态写入到临时或持久性存储区。以后,可以通过从存储区中读取或反序列化对象的状态,重新创建该对象。需要序列化的对象必须实现Serializable接口。Serializable接口没有任何的抽象方法,实现这个接口仅仅是为了通知编译器这个对象将要被序列化而已。对象中的transient和static类型成员变量不会被读取和写入。ObjectInputStream 将原数据和使用 ObjectOutputStream之前写入的 对象反序列化,ObjectInputStream 用来恢复之前序列化的对象。

上述代码通过ByteArrayOutputStream获取内存中的缓存数据并转成数组;而ByteArrayInputStream 将字节数组转化为输入流。

实际的数据流向:ObjectOutputStream->ByteArrayOutputStream->ByteArrayInputStream ->ObjectInputStream,深度复制从序列化对象又转为序列化对象