Serialization is basically deep cloning.
You need to track each link to objects for repetitions (for example, using IdentityHashMap ). Whatever your final implementation method (if not an external library), be sure to check for repeated calls or you may end up in an infinite loop (when object A refers to object B, which again refers to object A, or something more complex in graph objects).
One way is to go through the object graph using a DFS-like algorithm and build a clone there (serialized string).
This pseudo code, hopefully explains how:
visited = {} function visit(node) { if node in visited { doStuffOnReoccurence(node) return } visited.add(node) doStuffBeforeOthers(node) for each otherNode in node.expand() visit(otherNode) doStuffAfterOthers(node) }
The visited set in the example is where I should use the set of identifiers (if any) or IdentityHashMap.
When analyzing fields reflectively (thats node.expand ()), remember to also go through the fields of the superclass.
Reflection should not be used in a "normal" case of development. Reflection treats the code as data, and you can ignore all the usual object access restrictions. I used this deep copy reflective material for tests only:
source share