问题
clone method vs copy constructor in java. which one is correct solution. where to use each case?
回答1:
Clone is broken, so dont use it.
THE CLONE METHOD of the Object class is a somewhat magical method that does what no pure Java method could ever do: It produces an identical copy of its object. It has been present in the primordial Object superclass since the Beta-release days of the Java compiler*; and it, like all ancient magic, requires the appropriate incantation to prevent the spell from unexpectedly backfiring
Prefer a method that copies the object
Foo copyFoo (Foo foo){
Foo f = new Foo();
//for all properties in FOo
f.set(foo.get());
return f;
}
Read more http://adtmag.com/articles/2000/01/18/effective-javaeffective-cloning.aspx
回答2:
Have in mind that clone()
doesn't work out of the box. You will have to implement Cloneable
and override the clone()
method making in public
.
There are a few alternatives, which are preferable (since the clone()
method has lots of design issues, as stated in other answers), and the copy-constructor would require manual work:
BeanUtils.cloneBean(original) creates a shallow clone, like the one created by
Object.clone()
. (this class is from commons-beanutils)SerializationUtils.clone(original) creates a deep clone. (i.e. the whole properties graph is cloned, not only the first level) (from commons-lang), but all classes must implement
Serializable
Java Deep Cloning Library offers deep cloning without the need to implement
Serializable
回答3:
clone() was designed with several mistakes (see this question), so it's best to avoid it.
From Effective Java 2nd Edition, Item 11: Override clone judiciously
Given all of the problems associated with Cloneable, it’s safe to say that other interfaces should not extend it, and that classes designed for inheritance (Item 17) should not implement it. Because of its many shortcomings, some expert programmers simply choose never to override the clone method and never to invoke it except, perhaps, to copy arrays. If you design a class for inheritance, be aware that if you choose not to provide a well-behaved protected clone method, it will be impossible for subclasses to implement Cloneable.
This book also describes the many advantages copy constructors have over Cloneable/clone.
- They don't rely on a risk-prone extralinguistic object creation mechanism
- They don't demand unenforceable adherence to thinly documented conventions
- They don't conflict with the proper use of final fields
- They don't throw unnecessary checked exceptions
- They don't require casts.
All standard collections have copy constructors. Use them.
List<Double> original = // some list
List<Double> copy = new ArrayList<Double>(original);
回答4:
Keep in mind that the copy constructor limits the class type to that of the copy constructor. Consider the example:
// Need to clone person, which is type Person
Person clone = new Person(person);
This doesn't work if person
could be a subclass of Person
(or if Person
is an interface). This is the whole point of clone, is that it can can clone the proper type dynamically at runtime (assuming clone is properly implemented).
Person clone = (Person)person.clone();
or
Person clone = (Person)SomeCloneUtil.clone(person); // See Bozho's answer
Now person
can be any type of Person
assuming that clone
is properly implemented.
回答5:
See also: How to properly override clone method?. Cloning is broken in Java, it's so hard to get it right, and even when it does it doesn't really offer much, so it's not really worth the hassle.
回答6:
Great sadness: neither Cloneable/clone nor a constructor are great solutions: I DON'T WANT TO KNOW THE IMPLEMENTING CLASS!!! (e.g. - I have a Map, which I want copied, using the same hidden MumbleMap implementation) I just want to make a copy, if doing so is supported. But, alas, Cloneable doesn't have the clone method on it, so there is nothing to which you can safely type-cast on which to invoke clone().
Whatever the best "copy object" library out there is, Oracle should make it a standard component of the next Java release (unless it already is, hidden somewhere).
Of course, if more of the library (e.g. - Collections) were immutable, this "copy" task would just go away. But then we would start designing Java programs with things like "class invariants" rather than the verdammt "bean" pattern (make a broken object and mutate until good [enough]).
来源:https://stackoverflow.com/questions/2427883/clone-vs-copy-constructor-which-is-recommended-in-java