This week's book giveaway is in the OO, Patterns, UML and Refactoring forum. We're giving away four copies of Refactoring for Software Design Smells: Managing Technical Debt and have Girish Suryanarayana, Ganesh Samarthyam & Tushar Sharma on-line! See this thread for details.
Serialization does deep cloning easily, but won't clone transient fields; also it only works for classes that are serializable which is a limitation in a generic solution. I can find all the declared fields in a class; if they are primitive copy them and if they are objects clone recursively. One problem is how do I clone an array? If the array has elements, I can create an array of the correct type and clone the objects recursively (however, I do not know how to clone generic arrays in Java 1.5). Another problem is what do I do if a field is not primitive or array? How do I know that it doesn't contain other objects? Is it the case that if it contains other objects it must be a Collection? Please help me to do deep cloning with transients. [ August 07, 2005: Message edited by: Alejandro Barrero ]
Your help will be greatly appreciated,
It sounds like you're trying to write a "deepClone(Object)" method which always does the right thing. That's simply not possible: "the right thing" depends on the class being cloned. Have you considered circular references, for example? Have you considered how to properly handle singleton classes, and immutable classes like String and Integer, that you'd find in the tree? The clone-by-serialization trick doesn't do the right thing in many of these circumstances, either. There's simply no single rule which always does the right thing.
Best to concentrate on solving some specific problem you have rather than trying to solve this insoluble problem.
You are correct; it is impossible to do a deep clone that always does the right thing. I apologize for not expressing myself correctly. What I want to do is a deep clone that does the same thing as with serialization but includes transient fields. I can do it recursively and I know how to handle multiple references to the same object and circular references. The method deepClone(Object obj) will construct a clone from the class with newInstance() (I am aware of the problems), get all the declared fields in obj and process them: If a field is a primitive it will be copied. If it is an array an array of the same type with the same length will be created; if the elements are primitive they will be copied, otherwise they will be cloned. I can find the type of the array from the class getComponentType(); if it is primitive I can create arrays easily, but if not I don't know how. Now, if a field is not primitive or is not an array, it could be a collection containing other objects (if it implements Collection, I know how to handle that); If it is a 'plain' object I can use recursion. At this point, I have a doubt: Is it possible to have an object that is not primitive, is not an array, it does not implement Collection and is not a 'plain' object. Could I get help with this approach? [ August 08, 2005: Message edited by: Alejandro Barrero ]
author and iconoclast
Ah. Well, the static java.lang.reflect.newInstance() method can create an array of any type, given a Class object that represents that type. But you can also clone() any array to get an array of the same size with the same contents.
As far as your other question about placing a variable into four categories: a variable is either a primitive, or a reference type. If it's a reference type, it's either an array, or not. If it's not an array, it's either a Collection, or not. Those all seem like perfect binary branches, to me, so I don't think you've left anything out.
Joined: Aug 01, 2005
Thank you very much. I am on my way to creating my deepClone method.