Reputation: 1267
I understand how Java cloning works and the arguments against using it. Lets say I am dead set on using it anyway.
For the sake of convenience I would like to write a clone method for class Foo as follows:
@Override
public Foo clone(){
Foo f = (Foo)super.clone();
//Replace mutable fields
return f;
}
As far as I can tell this would be safe. However, I noticed that Cloneable classes in the API do not do this. Is there a reason for this and is it bad style?
Upvotes: 18
Views: 675
Reputation: 1926
Hmm, this is definitely not a bad style in fact its preferable that you do this since the release of java 1.5, because covariant return types were introduced in release 1.5 as part of generics, and by doing so, you are making your API easier to use (no casting would be required).
source (Effective java 2nd edition).
Upvotes: 3
Reputation: 37645
Object.clone()
creates a new object where all fields have the same value as the original. For fields of reference type, this means that the new field is simply a reference to the same object as the original. It does not clone
fields. Therefore in many cases, the default implementation would lead to shared data, which may be undesirable. For example, if ArrayList.clone()
used the default implementation, you would end up with two ArrayList
instances sharing the same backing array.
If all the fields of an object are immutable, it may be a good idea to simply cast the result of super.clone()
to the appropriate type.
Upvotes: 3
Reputation: 73538
Back before Java 5, covariant return types weren't allowed at all, so Foo clone()
wouldn't even compile.
Since a lot of Cloneable
classes have been written a long time ago, that's probably the reason for majority of the cases.
I suspect that newer classes don't use it simply because clone()
is known to be quite a handful, and when people rarely do use it, they don't even think that they could cast it. They find some "how to implement clone()" question and write the code in the old fashioned way.
Upvotes: 17