Recommended: Sing it, brah! 5 fabulous songs for developers
JW's Top 5
Optimize with a SATA RAID Storage Solution
Range of capacities as low as $1250 per TB. Ideal if you currently rely on servers/disks/JBODs
Page 3 of 7
Running the test with the OBJECT_CLONE variable set to true on a Windows 550-MHz machine with Sun Microsystems' JDK 1.4.1 produces:
clone implementation: Object.clone() method duration: 0.033 ms
This is not bad for a class with multiple primitive and object reference fields. But for better insight, I must compare the result with other approaches below.
Despite its advantages, this approach is plagued with problems due to poor java.lang.Object.clone() design. It cannot be used for cloning final fields unless they can be copied shallowly. Creating smart, deeply cloning container
classes is complicated by the fact that Cloneable is just a marker interface, and java.lang.Object.clone() is not public. Finally, cloning inner classes does not work due to problems with outer references. See articles by Mark Davis
and Steve Ball in Resources for some of the earliest discussions about this topic.
This approach complements Approach 1. It involves these steps:
X, provide a copy constructor with signature X(X x).clone() or directly to the base copy constructor. The former choice is more polymorphic and works when the base copy constructor
is private, and the latter sometimes avoids the small cost of casting clone()'s return value to a specific type.Setting COPY_CONSTRUCTOR to true and rerunning the test produces:
clone implementation: copy construction method duration: 0.024 ms
This beats Approach 1. The result might not be surprising because the overhead of native method calls has increased and the cost of new object creation has decreased with increasing JDK versions. If you rerun the same tests in Sun's JDK 1.2.2, the situation favors Approach 1. Of course, performance depends on the relative mix of shallow and deep fields in the class hierarchy. Classes with many primitive type fields benefit more from Approach 1. Classes with a few mostly immutable fields work very efficiently with Approach 2, with a speed advantage at least 10 times greater than Approach 1.
Approach 2 is more error prone than Approach 1 because it is easy to forget to override clone() and accidentally inherit a superclass's version that will return an object of the wrong type. If you make the same mistake
in Approach 1, the result will be less disastrous. Additionally, it is harder to maintain the implementation in Approach 2
when fields are added and removed (compare the OBJECT_CLONE branch in TestBaseClass.clone() with similar code in the copy constructor). Also, Approach 1 requires less class cooperation in some cases: for a base class
with only shallow fields, you don't need to implement Cloneable or even provide a clone() override if you do not intend to clone at the base class level.