Clone() VS Copy Constructor VS Factory Method

clone() vs copy constructor vs factory method?

Basically, clone is broken. Nothing will work with generics easily. If you have something like this (shortened to get the point across):

public class SomeClass<T extends Copyable> {

public T copy(T object) {
return (T) object.copy();
}
}

interface Copyable {
Copyable copy();
}

Then with a compiler warning you can get the job done. Because generics are erased at runtime, something that does a copy is going to have a compiler warning generating cast in it. It is not avoidable in this case.. It is avoidable in some cases (thanks, kb304) but not in all. Consider the case where you have to support a subclass or an unknown class implementing the interface (such as you were iterating through a collection of copyables that didn't necessarily generate the same class).

Clone() vs Copy constructor- which is recommended in java

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

Does cloning provide a performance improvement over constructors/factory methods?

One reason to invoke clone() instead of the copy constructor or a factory method is that none of the other options may be available.

Implementing clone() to perform a shallow object copy (deep copy is more involved) is trivial compared to implementing a copy constructor or a factory method to perform the same operation. To implement clone(), a class need simply implement the Cloneable interface and override method clone() with one that invokes super.clone() which usually invokes Object.clone(). Object.clone() copies every property of the original object into the corresponding property of the duplicate, thus creating a shallow copy.

Though implementing clone() is straightforward, it is still easy to forget to implement Cloneable. Consequently, a potential risk of using clone() to duplicate an object is that if the class of that object does neglect to implement Cloneable and clone() invokes Object.clone() either directly or indirectly, it will throw CloneNotSupportedException.

See this code example and a previous discussion on the poor design of the Cloneable interface.

Java clone() method using new keyword and a copy constructor instead of super.clone()

You are trying to clone by implementing cloneable interface but not following recommended contracts of cloning.

You are basically creating new object using copy constructor, my question is then why do you need to implement cloneable?

If you are implementing cloneable then you must respect the contracts. When you use copy constructor inside clone method then i will not recommend this approach simply because clone of it child class will not be an object of child class and intstead will be an object of Person class.

Also want to point out that, using copy constructor instead of cloneable interface is more object oriented approach.

Purpose of Copy Constructor when Clone Method exists?

As I understand, it is much up to your design intentions which one you would use, but the clone() method is generally considered to be broken. This may be a good reason designers add a proper copy constructor.

Here are some pros and cons:

  • The clone() method is considered to rise problems. For one thing, by default it is not clear if a deep or a shallow copy is meant. If you call super.clone() up the hierarchy, you may end up having a shallow copy of a mutable object, which was not your intention.
  • Some people use clone() for arrays only, as there it is faster.
  • Cloneable is unclear. If something is Cloneable, it may still be very unclear what you really can do with, as it has no public clone() method and neither has Object.
  • The copy constructor has the advantage of handling generics (as Stephen C shows).

Here are some interesting sources to read:

  • http://www.javapractices.com/topic/TopicAction.do;jsessionid=E02323AC2EB0E257338BA5C8755A9D4C?Id=71
  • http://www.artima.com/intv/bloch13.html
  • clone() vs copy constructor vs factory method?
  • Copy constructor versus Clone()

Then, you've asked for source code of ArrayList copy constructor and clone:

ArrayList(Collection<? extends E> c) {
elementData = c.toArray();
size = elementData.length;
// c.toArray might (incorrectly) not return Object[] (see 6260652)
if (elementData.getClass() != Object[].class)
elementData = Arrays.copyOf(elementData, size, Object[].class);
}

public Object clone() {
try {
@SuppressWarnings("unchecked")
ArrayList<E> v = (ArrayList<E>) super.clone();
v.elementData = Arrays.copyOf(elementData, size);
v.modCount = 0;
return v;
} catch (CloneNotSupportedException e) {
// this shouldn't happen, since we are Cloneable
throw new InternalError();
}
}

Got this from CodeGrep.

Performance of Cloning (either by Cloneable Interface or Copy Constructor) a object vs Creating a new object in Prototype Pattern

The prototype pattern isn't used for performance (although according to Ioannis' link, it has been used as a performance hack). It's used so you can create new objects from a (possibly changing) prototype.

Some method of "cloning" is needed so you don't have to care about the state of prototype. You can just call prototype.someMethodThatReturnsACopy() and the object is ready for use. You could use clone() or some other way to create that copy, even manually constructing one if you really want.



Related Topics



Leave a reply



Submit