If a Java class implements the Serializable
interface but does not have a public clone()
method, it is usually possible to create a deep copy like this:
class CloneHelper {
@SuppressWarnings("unchecked")
public static <T extends Serializable> T clone(T obj) {
try {
ByteArrayOutputStream baos = new ByteArrayOutputStream();
ObjectOutputStream oos = new ObjectOutputStream(baos);
oos.writeObject(obj);
oos.close();
byte[] bytes = baos.toByteArray();
ByteArrayInputStream bais = new ByteArrayInputStream(bytes);
ObjectInputStream ois = new ObjectInputStream(bais);
T copy = (T) ois.readObject();
ois.close();
return copy;
} catch (ClassNotFoundException ex) {
// Shouldn't happen
throw new Error(ex);
} catch (IOException ex) {
// Probably a bug in T's custom serialization methods
throw new RuntimeException(ex);
}
}
}
I often encounter third-party library classes like this and resort to hacks like the one above. I've even extended ObjectOutputStream
on occasion to make the copy shallower. It's never caused serious problems, other than being inefficient (slow to encode/decode and the temporary serialization graphs can consume a lot of memory.)
And if it is not safe to use this technique, the class probably should not have been declared Serializable
.
So what I would like to know is, if your class is Serializable
, what might prevent you from defining a public clone()
method (using either the Cloneable
interface or a copy constructor?)
Related: Copy an object in Java