Home | Contact Us | FAQ | Search & Site Map | Link to Us
Sign In | Join | Other 45 Sites in Network
HomeAnnouncementsWhite Papers
Discussion GroupsFirst AidDatabasesJavaBeansGUIJava 3DVirtual MachineCORBASecurityToolsGeneral
Java DirectoryOpen Source ProjectsSample Book ChaptersUser GroupsWeb Resources
Related Topics
Databases.NETMore Topics ...

Java Forum / General / December 2005

Tip: Looking for answers? Try searching our database.

How to clone objects?

Thread view: 
moop™ - 08 Dec 2005 15:04 GMT
Hi,
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!
Viator - 08 Dec 2005 15:18 GMT
I am not commenting on the design that but for that you have to
implement Cloneable interface.

Amit :-)
J. Verdrengh - 08 Dec 2005 15:33 GMT
In my experience, the way with the least potential problems is defining a
new instance method (like YourClass.duplicate() ) or a copy constructor
(like YourClass.YourClass(YourClass copyMe) ) in which you create a copy of
<this> / <copyMe>. This way you don't have to think about overriding clone()
and the consequences of doing that.

Jeroen
Chris Smith - 08 Dec 2005 15:58 GMT
> In my experience, the way with the least potential problems is defining a
> new instance method (like YourClass.duplicate() ) or a copy constructor
> (like YourClass.YourClass(YourClass copyMe) ) in which you create a copy of
> <this> / <copyMe>. This way you don't have to think about overriding clone()
> and the consequences of doing that.

On the other hand, if you want a clone, why would you avoid clone()?  If
this class may have subclasses, then the copy constructor won't work...
and if its constructors have side-effects, you can't reliably create a
clone WITHOUT calling Object.clone() at some point.  These are the
problems that clone() was invented to solve.

Signature

www.designacourse.com
The Easiest Way To Train Anyone... Anywhere.

Chris Smith - Lead Software Developer/Technical Trainer
MindIQ Corporation

The Conqueror - 08 Dec 2005 16:05 GMT
Create a copy constructor for it.Thats the easiest option for you.
Chris Smith - 08 Dec 2005 19:01 GMT
> Create a copy constructor for it.Thats the easiest option for you.

Once again... if there's every a chance that this class will have
subclasses, a copy constructor is NOT a reasonable choice.

Signature

www.designacourse.com
The Easiest Way To Train Anyone... Anywhere.

Chris Smith - Lead Software Developer/Technical Trainer
MindIQ Corporation

Roedy Green - 09 Dec 2005 00:02 GMT
>Once again... if there's every a chance that this class will have
>subclasses, a copy constructor is NOT a reasonable choice.

Are you sure?  I think the default clone implementation just copies
all bytes in the given object.  That should produce a cloned subclass
as well.  Has anyone done an experiment to see if clone gives you the
class where clone was defined or the subclass of the cloned object?
Signature

Canadian Mind Products, Roedy Green.
http://mindprod.com Java custom programming, consulting and coaching.

Chris Smith - 09 Dec 2005 00:50 GMT
> >Once again... if there's every a chance that this class will have
> >subclasses, a copy constructor is NOT a reasonable choice.
[quoted text clipped - 3 lines]
> as well.  Has anyone done an experiment to see if clone gives you the
> class where clone was defined or the subclass of the cloned object?

You seem to have misunderstood.

Clone will do the right thing.  That is, the class of the resulting
object is the same as the class of the object that's cloned.  This is
different from a "copy constructor" (C++ terminology) which will produce
an object of some compile-time known class that may be a superclass of
the object.  In other words, C++ style copy constructors exhibit a
truncation problem for subclasses, while clone solves that problem.

(Note that this is fine for the situation in which C++ copy constructors
are meant to be used... when passing or returning "auto" objectoids
whose class is necessarily known at compile-time anyway.  C++ will never
apply a copy constructor implicitly when passing pointers to true
objects.  It's just when you try to apply it to true objects that copy
constructors fail with subclasses.)

Signature

www.designacourse.com
The Easiest Way To Train Anyone... Anywhere.

Chris Smith - Lead Software Developer/Technical Trainer
MindIQ Corporation

Darryl L. Pierce - 09 Dec 2005 19:57 GMT
> Create a copy constructor for it.Thats the easiest option for you.

Why, when Java gives you both the Object.clone() method and the
Cloneable interface? Copy constructors are a C++ paradigm.

Signature

Darryl L. Pierce <mcpierce@gmail.com>
Homepage: http://mcpierce.multiply.com/
"Bury me next to my wife. Nothing too fancy, though..." - Ulysses S. Grant

J. Verdrengh - 08 Dec 2005 17:58 GMT
> On the other hand, if you want a clone, why would you avoid clone()?

One reason could be because the semantics of clone() are ambiguous: the same
method is used for deep copying in one class & shallow copying in another
class.
Thomas Weidenfeller - 09 Dec 2005 12:51 GMT
> One reason could be because the semantics of clone() are ambiguous: the same
> method is used for deep copying in one class & shallow copying in another
> class.

So what? If it is your own class, you implement whatever cloning
behavior you want in the clone() method.

/Thomas
Signature

The comp.lang.java.gui FAQ:
ftp://ftp.cs.uu.nl/pub/NEWS.ANSWERS/computer-lang/java/gui/faq
http://www.uni-giessen.de/faq/archiv/computer-lang.java.gui.faq/

J. Verdrengh - 09 Dec 2005 14:41 GMT
> So what? If it is your own class, you implement whatever cloning
> behavior you want in the clone() method.

you're right
Chris Smith - 08 Dec 2005 15:55 GMT
moop? <samhng@gmail.com> wrote:
> 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
[quoted text clipped - 3 lines]
> 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.

Signature

www.designacourse.com
The Easiest Way To Train Anyone... Anywhere.

Chris Smith - Lead Software Developer/Technical Trainer
MindIQ Corporation

zero - 08 Dec 2005 17:49 GMT
> Cloning is a little complicated.  The steps are as follows:
>
[quoted text clipped - 21 lines]
>                 MyPrototype other = (MyPrototype) super.clone();
>                 other.lastUse = lastUser.clone();

you probably mean other.lastUse = lastUse.clone(); right?

<snip>

Seems like a good explanation.  Ever think of putting it online?  Or maybe
Roedy could put it on mindprod.

Signature

Beware the False Authority Syndrome

Chris Smith - 08 Dec 2005 19:00 GMT
> you probably mean other.lastUse = lastUse.clone(); right?

Yes. :)  And I messed a necessary cast.

Signature

www.designacourse.com
The Easiest Way To Train Anyone... Anywhere.

Chris Smith - Lead Software Developer/Technical Trainer
MindIQ Corporation

Alex Molochnikov - 09 Dec 2005 01:17 GMT
> Yes. :)  And I messed a necessary cast.

You also messed this part:

> 4. Have the clone method recursively clone any nonmutable objects that
are components of this one.

It took me by surprise until I reached the end of the post and realized that
"nonmutable" was a typo, meant to spell "mutable".

Alex Molochnikov
Gestalt Corporation
Chris Smith - 09 Dec 2005 01:34 GMT
> You also messed this part:
>
[quoted text clipped - 3 lines]
> It took me by surprise until I reached the end of the post and realized that
> "nonmutable" was a typo, meant to spell "mutable".

Yes, that's right.

Signature

www.designacourse.com
The Easiest Way To Train Anyone... Anywhere.

Chris Smith - Lead Software Developer/Technical Trainer
MindIQ Corporation

Chris Smith - 09 Dec 2005 01:35 GMT
> Seems like a good explanation.  Ever think of putting it online?  Or maybe
> Roedy could put it on mindprod.

I would if JINX worked reliably.  Roedy is welcome to it, though the
corrections should be applied.

Signature

www.designacourse.com
The Easiest Way To Train Anyone... Anywhere.

Chris Smith - Lead Software Developer/Technical Trainer
MindIQ Corporation

Roedy Green - 08 Dec 2005 23:36 GMT
>But I don't know how to use the clone() method suitablely,
>anyone helps?

see http://mindprod.com/jgloss/clone.html
for sample code.
Signature

Canadian Mind Products, Roedy Green.
http://mindprod.com Java custom programming, consulting and coaching.



Free Magazines

Get these publications absolutely FREE for up to 12 months. There are no hidden fees and no obligation. Simply choose a title, complete the application form and submit it. Read more ...

Oracle MagazineNetwork ComputingComputer WorldBio-IT WorldeWeekInformation WeekInfosecurity
 
Sign In
Join
My Latest Posts
My Monitored Threads
My Blog
My Photo Gallery
My Profile
My Homepage

Start New Thread
Enable EMail Alerts
Rate this Thread



©2008 Advenet LLC   Privacy Policy - Terms of Use
This website includes both content owned or controlled by Advenet as well as content owned or controlled by third parties.