Win a copy of Functional Reactive Programming this week in the Other Languages forum!
  • Post Reply
  • Bookmark Topic Watch Topic
  • New Topic

Question about Object.clone() discussion in the API

 
Ruben Soto
Ranch Hand
Posts: 1032
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
I don't understand what this portion of the Object.clone() API text means:


By convention, the returned object should be obtained by calling super.clone. If a class and all of its superclasses (except Object) obey this convention, it will be the case that x.clone().getClass() == x.getClass().


I know I am overlooking something, which hopefully someone can clarify.

Thanks,

Ruben
 
Mike Simmons
Ranch Hand
Posts: 3090
14
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Let's say I have a class:

The clone method here seems reasonable enough. Given a Foo instance, it provides an identical copy. But what if we extend the class?

Note that I had to set x as well as y. It would have been nice if I could have called super.clone() to take care of that, since the code in Foo.clone() already handled that situation. But I couldn't, because Foo.clone() created a Foo instance. Not a Bar, which is what I needed. So I had to create my own new Bar() and populate its fields. Which wasn't too difficult, since in this example I had just one field in Foo, and one additional field in Bar. But imagine if each class had ten new fields of their own. And if we extended Bar with Baz, or more. A complex class hierarchy would have a [/i]lot[/i] of duplicated code, just in the clone() methods. The advice given in the clone() documentation is a way to avoid that:

There's much less repetition this way. And it's possible to do other things in the clone() methods, in addition to calling super.clone(). But always calling super.clone() will ensure that at least the class of the clone is correct - because that's one of the things that Object's clone() method does for you. It also copies all fields, shallowly. So the main decision you have is whether you want to replace those shallow copies with deeper copies.

 
Shashank Rudra
Ranch Hand
Posts: 131
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Here I have a question - which clone() will set the value of X that is being inherited by Bar from Foo. If the clone() method as being used with super() is doing that- isn't it doing a deep copy?
 
Ruben Soto
Ranch Hand
Posts: 1032
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Mike Simmons wrote:
There's much less repetition this way. And it's possible to do other things in the clone() methods, in addition to calling super.clone(). But always calling super.clone() will ensure that at least the class of the clone is correct - because that's one of the things that Object's clone() method does for you. It also copies all fields, shallowly. So the main decision you have is whether you want to replace those shallow copies with deeper copies.


Hi Mike,

Thank you, that was a brilliant explanation and made things clear. I checked the source for Object, and it appears that clone() is a native method. My guess is that it performs some low level reflection magic to make sure that all the fields are copied shallowly, and to make sure that an instance of the correct class is instantiated.

I guess that if for example you wanted to perform deep copies of instance variables, you would do that after the call to super.clone() (by cloning the objects instance variables are bound to and rebinding each instance variable to each new cloned instance.)

Again, great explanation.
 
Ruben Soto
Ranch Hand
Posts: 1032
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Giffy Geraldo wrote:Here I have a question - which clone() will set the value of X that is being inherited by Bar from Foo. If the clone() method as being used with super() is doing that- isn't it doing a deep copy?

I am not sure I get your question, but I will give it a shot:

When you clone an object using the default clone() implementation from Object, which is what you ultimately are doing when you simply use super.clone(), you get a whole new object, but any objects which are bound to instance variables are not cloned.
For example, let's say you have an object of class A which has a x reference variable of type Integer. If you clone an object of class A, you get a new instance of class A, but its x reference variable will point to the same object as the x reference variable in the object which you cloned from. Maybe Mike can correct me (or you can tell me what I didn't understand from your question.)
 
  • Post Reply
  • Bookmark Topic Watch Topic
  • New Topic