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 Listwords; @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.