Attack of the clones

Time and space considerations in four different approaches to implementing deep clone() methods

1 2 3 Page 3
Page 3 of 3
        int count = 0;
        List list = new LinkedList ();
        try
        {
            while (true)
            {
                list.add (obj.clone ());
                ++ count;
            }
        }
        catch (Throwable t)
        {
            System.out.println ("count = " + count);
        }

Run this in a JVM with a -Xmx8m setting and you will see something similar to this:

>java -Xmx8m Main
clone implementation: Object.clone()
count = 5978 Exception in thread "main" java.lang.OutOfMemoryError
...
clone implementation: copy construction
count = 5978
...
clone implementation: serialization
count = 747
...
clone implementation: reflection
count = 5952

Approach 3's overhead increases with the number of immutable fields in a class. Removing this overhead is nontrivial.

The recap

The following table recaps the properties of all cloning approaches in this article from several perspectives: speed, resource utilization, class design constraints, object graph handling.

Object.clone()
Speed High
Resource utilization Low
Class design constraints Does not work with deep final fields; does not work with inner classes; must implement Cloneable; medium amount of manual class maintenance
Object graphs Does not handle object graphs transparently
Copy construction
Speed High
Resource utilization Low
Class design constraints Superclasses and subclasses must cooperate; copy constructor required; a lot of manual class maintenance
Object graphs Does not handle object graphs transparently
Serialization
Speed Low
Resource utilization High; creates redundant immutable fields
Class design constraints Must implement Serializable; first non-Serializable class needs an accessible no-arg constuctor
Object graphs Handles object graphs
Reflection
Speed Medium
Resource utilization Medium
Class design constraints Does not work with final fields; does not work with inner classes; each class must provide no-arg constructor
Object graphs Handles object graphs

This article discussed implementing a single method, Object.clone(). It is amazing that a single method can have so many implementation choices and subtle points. I hope this article provided you with some food for thought and useful guidelines for your application class design.

Vladimir Roubtsov has programmed in a variety of languages for more than 12 years, including Java since 1995. Currently, he develops enterprise software as a senior developer for Trilogy in Austin, Texas.

Learn more about this topic

1 2 3 Page 3
Page 3 of 3