9

I heard that you should avoid it in your code but it was implemented for some reason so is there a case where using it is actually a good (or not bad) choice or should I always try to avoid it?

kojkl
  • 93
  • 4
  • I wouldn't say you should avoid it. Like almost everything, you can use it right or wrong... Read something about prototype pattern, that's how you can use it right... – Jaa-c Oct 26 '14 at 22:10
  • When unsure, implement it yourself, or preferably if possible, check out the source. The potholes of using clone() is mainly that you cannot always know if it works as intended (unless you test it, of course). For example, I've had a hard time getting a clone of an int array. The documentation of clone however states that it should return a copy of the object, so I'm waiting for an answer for this as well! – Olavi Mustanoja Oct 26 '14 at 22:11
  • 2
    I've never used it in 17 years, or a 'copy constructor' either. – user207421 Oct 26 '14 at 22:16
  • @EJP, You've never used the new ArrayList(list) copy constructor before? Or one of it's many variants? – Afforess Oct 26 '14 at 22:19
  • @Afforess It doesn't exist. `ArrayList(Collection extends E> c)` is not a copy constructor, in my book. `ArrayList(ArrayList extends E> list)` would be. I don't call something introduced in 1998 'new' either. – user207421 Oct 26 '14 at 22:31
  • 1
    @EJP I am not sure why you don't consider `ArrayList(Collection extends E> c)` a copy constructor when it performs exactly the same operation a `ArrayList(ArrayList extends E> list)` would. If it looks like a duck, and quacks like a duck, it's probably a duck... – Afforess Oct 26 '14 at 22:36

2 Answers2

10

Josh Bloch answered this perfectly:

If you've read the item about cloning in my book, especially if you read between the lines, you will know that I think clone is deeply broken. There are a few design flaws, the biggest of which is that the Cloneable interface does not have a clone method. And that means it simply doesn't work: making something Cloneable doesn't say anything about what you can do with it. Instead, it says something about what it can do internally. It says that if by calling super.clone repeatedly it ends up calling Object's clone method, this method will return a field copy of the original.

But it doesn't say anything about what you can do with an object that implements the Cloneable interface, which means that you can't do a polymorphic clone operation. If I have an array of Cloneable, you would think that I could run down that array and clone every element to make a deep copy of the array, but I can't. You cannot cast something to Cloneable and call the clone method, because Cloneable doesn't have a public clone method and neither does Object. If you try to cast to Cloneable and call the clone method, the compiler will say you are trying to call the protected clone method on object.

It's a shame that Cloneable is broken, but it happens. The original Java APIs were done very quickly under a tight deadline to meet a closing market window. The original Java team did an incredible job, but not all of the APIs are perfect. Cloneable is a weak spot, and I think people should be aware of its limitations.

Community
  • 1
  • 1
Afforess
  • 894
  • 7
  • 15
0

You Should try to always override the clone method depending on the object type, the java clone() method doesn't always do what you want.

see: Deep copy, shallow copy, clone

Community
  • 1
  • 1
kudeh
  • 883
  • 1
  • 5
  • 16