moop? said:
In my scenerio, building up a class is a difficult task and cost a lot
of time. I want to store a copy of the object, which has no specific
detail value. When request the object, I can clone a copy of that and
use the copy would not affect the original one, so I can change
whatever value of the cloned one and get another pure clones from the
original. But I don't know how to use the clone() method suitablely,
anyone helps? Thx!
Cloning is a little complicated. The steps are as follows:
1. Implement the Cloneable interface.
2. Override the clone method from Object.
3. Have the clone method call the superclass.
4. Have the clone method recursively clone any nonmutable objects that
are components of this one.
5. Unless clone is actually likely to fail because of step 4, convert
CloneNotSupportedException to a RuntimeException.
It looks like this:
public class MyPrototype implements Cloneable
{
int value; // primitive type
String name; // reference to immutable object
Date lastUse; // reference to mutable object
UserAccount lastUser; // reference to non-component object
public Object clone()
{
try
{
MyPrototype other = (MyPrototype) super.clone();
other.lastUse = lastUser.clone();
return other;
}
catch (CloneNotSupportedException e)
{
throw new RuntimeException(e);
}
}
}
A few notes:
(a)
Note that of the four fields, only one had to be explicitly copied in
the clone() method. In fact, all fields will be copied automatically by
the call to super.clone(). The thing to remember is that when a field
is a reference to an object, the reference is copied, and NOT the
object. So all primitive types are safe.
If the reference points to an immutable object, that's also safe. The
object is not copied, so it will be shared between the original and the
clone. Since it's immutable, though, that is okay. No operations on
the object can cause it to act differently for the twin. If one of the
other object reassigns their reference to a different object, the twin
won't be affected.
The last two references (lastUse and lastUser, to Date and UserAccount)
are the more subtle distinction. The Date is actually PART of the
concept of this object, so it needs to be copied (since Date is mutable)
to prevent the last use date of this object from being changed when its
twin is used. The UserAccount, though, is NOT part of the meaning of
this object. It's just associated with this object. We don't need a
second UserAccount when cloning this object.
(b)
Why swallow the checked exception? Because if someone has a reference
to MyPrototype, they should be confident that it can be cloned. You
don't want to force them to handle at compile time the possibility that
you screwed up and forgot to implement Cloneable or called clone() on a
non-Cloneable field.
If you do NOT think they should be confident of this for some reason
(for example, because you're calling clone() on arbitrary Object
references that they passed in), then feel free to not swallow the
exception and document why it won't occur.
--
www.designacourse.com
The Easiest Way To Train Anyone... Anywhere.
Chris Smith - Lead Software Developer/Technical Trainer
MindIQ Corporation