Marker interfaces and deep copies - 1

"Hi, Amigo!"

"Hi, Bilaabo!"

"Today I'll tell you about marker interfaces."

"Marker interfaces are interfaces without methods. When a class implements such an interface, we say that it is marked by it."

"Examples of these interfaces include: Cloneable, Serializable, Remote."

"The Serializable interface is used to mark classes that support serialization, indicating that instances of these classes can be automatically serialized and deserialized."

"The Remote interface is used to identify objects that support remote execution, i.e. methods that can be invoked from another Java virtual machine and/or different computer."

"The Cloneable interface is used to mark classes that support cloning."

"Oh, about cloning, or copying."

"There are two types of copying: shallow and deep."

"Shallow copying is creating a copy of an object, without making duplicates of any of the objects it references."

"Deep copying involves duplicating an object, including objects it references, and the objects that those objects reference, etc."

"There is a really good way to reliably create a deep clone."

"This method works even if developers have forgotten to mark a class as Cloneable. "The only requirement is that the objects must be serializable."

"Here is how you do it:"

1) Create a buffer (byte array) in memory.

2) Serialize the object and subobjects into the buffer.

3) Deserialize the object hierarchy saved in the buffer.

Code
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();

"In the first line, we create objectOriginal, which we will clone. The object and all of its subobjects must support serialization."

"In the third line, we create a ByteArrayOutputStream, which will expand dynamically as new data is added (like an ArrayList)."

"In line 4, we create an ObjectOutputStream, which is used for serialization."

"In line 5, we serialize objectOriginal into a byte array using outputStream and save it to writeBuffer."

"In line 8, we convert writeBuffer into an ordinary byte array. Later we will 'read' our new object from this array."

"In line 9, we transform buffer into a ByteArrayInputStream in order to read from it like an InputStream."

"In line 10, we pass readBuffer to the ObjectInputStream constructor to read (deserialize) the object."

"In line 11, we read our object and convert it to a BigObject."

"What do you think?"

"It's beautiful."

"And by the way, when the code is highlighted in different colors, it's much easier to understand."