Today I had to deep clone objects in Java. What a nightmare.
First, the Cloneable interface is horribly broken, and writing such a simply code becomes a laborious task. Second, if the object has a List as a field, you must manually clone the elements into a new List.
The code goes as it follows:
public class Foo implements Cloneable {
private String name;
private List words;
@Override
public Object clone() {
try {
Foo cloned = (Foo) super.clone();
cloned.words = Auxiliar.cloneList(words);
return cloned;
} catch (CloneNotSupportedException e) {
System.out.println("Never happens!");
return null;
}
}
// Getters and setters omitted.
}
Notice the Another.cloneList() call? This is where we manually clone all the List elements, by calling clone() in each one. This is the solution I found for a generic method:
public class Auxiliar {
@SuppressWarnings("unchecked")
public static <T extends Cloneable> List<T> cloneList(List<T> list) {
try {
List<T> newList = new ArrayList<>(list.size());
for (T item : list) {
newList.add((T) item.getClass().getMethod("clone").invoke(item));
}
return newList;
} catch (IllegalAccessException | IllegalArgumentException
| InvocationTargetException | NoSuchMethodException | SecurityException e) {
System.out.println("Never happens!");
return null;
}
}
}
No idea why Cloneable was not deprecated and replaced by something minimally decent yet.