Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

clone() vs copy constructor vs factory method?

Tags:

java

clone

I did a quick google on implementing clone() in Java and found: http://www.javapractices.com/topic/TopicAction.do?Id=71

It has the following comment:

copy constructors and static factory methods provide an alternative to clone, and are much easier to implement.

All I want to do is make a deep copy. Implementing clone() seems to make a lot of sense, but this highly google ranked article makes me a bit afraid.

Here are the issues that I've noticed:

Copy constructors don't work with Generics.

Here's some pseudo-code that won't compile.

public class MyClass<T>{    ..    public void copyData(T data){        T copy=new T(data);//This isn't going to work.        }    .. } 

Sample 1: Using a copy constructor in a generic class.

Factory methods don't have standard names.

It's quite nice to have an interface for reusable code.

public class MyClass<T>{     ..     public void copyData(T data){         T copy=data.clone();//Throws an exception if the input was not cloneable     }     .. } 

Sample 2: Using clone() in a generic class.

I noticed that clone is not a static method, but wouldn't it still be necessary to make deep copies of all the protected fields? When implementing clone(), the extra effort to throw exceptions in non-cloneable subclasses seems trivial to me.

Am I missing something? Any insights would be appreciated.

like image 293
User1 Avatar asked Jul 09 '09 19:07

User1


People also ask

What is the difference between copy constructor and clone?

In Java, we can also use the clone method to create an object from an existing object. However, the copy constructor has some advantages over the clone method: The copy constructor is much easier to implement. We do not need to implement the Cloneable interface and handle CloneNotSupportedException.

What is clone () method?

clone() method in Java Object class has a clone method which can be used to copy the values of an object without any side-effect. Assignment operator has a side-effect that when a reference is assigned to another reference then a new object is not created and both the reference point to the same object.

Does clone () make a deep copy?

clone() is indeed a shallow copy. However, it's designed to throw a CloneNotSupportedException unless your object implements Cloneable . And when you implement Cloneable , you should override clone() to make it do a deep copy, by calling clone() on all fields that are themselves cloneable.

What is the alternative for copy constructor in Java?

We can also use the clone() method to get a copy of an object from an existing object of the class. But the Copy constructor is better to use than the clone() method because of the following reasons: 1. It is easier to implement and use a copy constructor than the clone() method.


1 Answers

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).

like image 55
Yishai Avatar answered Sep 22 '22 13:09

Yishai