标记接口和深拷贝 - 1

“嗨,阿米戈!”

“嗨,比拉博!”

“今天给大家说说标记接口。”

“标记接口是没有方法的接口。当一个类实现了这样的接口时,我们说它被它标记了。”

“这些接口的示例包括:Cloneable、Serializable、Remote。”

Serializable接口用于标记支持序列化的类,表示这些类的实例可以自动序列化和反序列化。”

远程接口用于识别支持远程执行的对象,即可以从另一个 Java 虚拟机和/或不同计算机调用的方法。”

Cloneable接口用于标记支持克隆的类。”

“哦,关于克隆或复制。”

“有两种类型的复制:浅层和深层。”

浅复制是创建一个对象的副本,而不复制它引用的任何对象。”

深度复制涉及复制一个对象,包括它引用的对象,以及这些对象引用的对象等。”

“有一种非常好的方法可以可靠地创建深度克隆。”

“即使开发人员忘记将类标记为可克隆,此方法也能正常工作。唯一的要求是对象必须是可序列化的。”

“这是你如何做的:”

1)在内存中创建一个缓冲区(字节数组)。

2)将对象和子对象序列化到缓冲区中。

3)反序列化缓冲区中保存的对象层次结构。

代码
BigObject objectOriginal = new BigObject();

ByteArrayOutputStream writeBuffer = new ByteArrayOutputStream();
ObjectOutputStream outputStream = new ObjectOutputStream(writeBuffer);
outputStream.writeObject(objectOriginal);
outputStream.close();

byte[] buffer = writeBuffer.toByteArray();
ByteArrayInputStream readBuffer = new ByteArrayInputStream(buffer);
ObjectInputStream inputStream = new ObjectInputStream(readBuffer);
BigObject objectCopy = (BigObject)inputStream.readObject();

“在第一行中,我们创建了objectOriginal,我们将克隆它。该对象及其所有子对象必须支持序列化。”

“在第三行,我们创建了一个ByteArrayOutputStream,它会随着新数据的添加而动态扩展(就像一个 ArrayList)。”

“在第 4 行中,我们创建了一个用于序列化的ObjectOutputStream 。”

“在第 5 行,我们使用outputStream将objectOriginal序列化为一个字节数组 ,并将其保存到writeBuffer中。”

“在第 8 行,我们将writeBuffer转换为一个普通的字节数组。稍后我们将从这个数组中‘读取’我们的新对象。”

“在第 9 行中,我们将缓冲区转换为ByteArrayInputStream,以便像 InputStream 一样从中读取。”

“在第 10 行,我们将readBuffer传递给ObjectInputStream构造函数以读取(反序列化)对象。”

“在第 11 行,我们读取了我们的对象并将其转换为 BigObject

“你怎么认为?”

“很美丽。”

“顺便说一句,当代码以不同颜色突出显示时,它更容易理解。”