3

My, perhaps naive, solution for cloning an ArrayList (Vector replacement) is

ArrayList<Double> alBis = (ArrayList<Double>) alOriginal.clone();

considering that because the array contains immutable Doubles, I don't need to clone them, but only the container.

As clone() returns an Object I put there the cast, but then -Xlint complains it is an unchecked cast.

So, what now? Ignore it with supressWarnings? Create a new ArrayList and copy the orginal elements with a compact for? Any library method similar to Arrays.copyOf()?

I read Unchecked cast warning but the accepted way is incredible complex.

Community
  • 1
  • 1
cibercitizen1
  • 20,944
  • 16
  • 72
  • 95

3 Answers3

14

clone() has major flaws, see this Question for reference. Don't use it!

Instead, all standard Collections have copy constructors. Use them:

List<Double> original = // some list
List<Double> copy = new ArrayList<Double>(original);

Reference:

Community
  • 1
  • 1
Sean Patrick Floyd
  • 292,901
  • 67
  • 465
  • 588
  • "clone() has major flaws" Can you elaborate? I haven't noticed any in the answers to the linked question. – adamax Feb 23 '11 at 17:53
  • Read Effective Java by Joshua Bloch – Sean Patrick Floyd Feb 23 '11 at 17:59
  • When considering use of a clone versus a copy constructor, one needs to consider what should happen if the passed-in object is of a class derived from the expected class. In the case of clone, the new object will be the same class as the original; in the case of a copy constructor, it will be of the expected class. In some cases, one behavior will be correct and the other decidedly wrong, with different behavior required in different cases. – supercat Feb 23 '11 at 18:17
  • @supercat nonsense. You can't invoke clone() without knowing what class you are dealing with, because clone() is not backed by any interface (Cloneable is just a marker interface). With thqt same knowledge, you can choose the Copy constructor of the correct class. – Sean Patrick Floyd Feb 23 '11 at 18:53
  • and by the same logic (clone is not backed by any interface) using clone() also violates Effective Java Item 52: "Refer to objects by their interfaces" – Sean Patrick Floyd Feb 23 '11 at 19:48
  • @Sean: If an extensible class Foo supports cloning, and Bar which derives from foo also supports cloning, then a routine which accepts a Foo may try to clone it even if it's a Bar. In many such cases, the new object produced by the cloning operation should be a Bar. If what's needed is a Foo whose Foo-ish properties match those of the Bar, and whose Bar-specific properties are stripped out, a copy constructor might be appropriate, but otherwise I would suggest that a Clone should in 99.44% of cases return an object of the same actual type as the original. – supercat Feb 23 '11 at 20:13
  • @supercat a) yup, that's what they thought when they designed the clone mechanism. But the same people [are now telling us there is a flaw in the process](http://books.google.de/books?id=ka2VUBqHiWkC&pg=PA54&lpg=PA54&dq=Override+clone+judiciously&source=bl&ots=yXLnMnp_P0&sig=CgOAr2K2b5khhXZN0zxi867Y_IQ&hl=en&ei=52plTdmuJqGH4gagqYHcBg&sa=X&oi=book_result&ct=result&resnum=6&ved=0CDkQ6AEwBQ#v=onepage&q=Override%20clone%20judiciously&f=false). b) in the context of the question there is no hierarchy. ArrayList should hardly ever be subclassed and it's parents don't support clone(). – Sean Patrick Floyd Feb 23 '11 at 20:19
4

Is it wrong to use .clone()?

It should be avoided whenever possible. It is an obsolete, badly designed and fundamentally broken API. Better use the copy constructor as @Sean suggested.

Community
  • 1
  • 1
Péter Török
  • 114,404
  • 31
  • 268
  • 329
1

Personally I would recommend Google guava-libraries, and:

 ImmutableCollection<Double> copy = ImmutableList.copyOf(original);

And do not use JRE clone, because it sucks (if you want to know why, then read references).

Reference:

Margus
  • 19,694
  • 14
  • 55
  • 103