Clone (Java method)
clone
is a method in the Java programming language for object duplication. In Java, objects are manipulated through reference variables, and there is no operator for copying an object—the assignment operator duplicates the reference, not the object. The clone method provides this missing functionality.Overview
Classes that want copying functionality must implement some method to do so. To a certain extent that function is provided by "Object.clone
".clone
acts like a copy constructor. Typically it calls the clone
method of its superclass to obtain the copy, etc. until it eventually reaches Object
's clone
method. The special clone
method in the base class Object
provides a standard mechanism for duplicating objects.The class
Object
's clone
method creates and returns a copy of the object, with the same class and with all the fields having the same values. However, Object.clone
throws a CloneNotSupportedException
unless the object is an instance of a class that implements the marker interface Cloneable
.The default implementation of
Object.clone
performs a shallow copy. When a class desires a deep copy or some other custom behavior, they must implement that in their own clone
method after they obtain the copy from the superclass.The syntax for calling
clone
in Java is :Object copy = obj.clone;
or commonly
MyClass copy = obj.clone;
which provides the typecasting needed to assign the general
Object
reference returned from clone
to a reference to a MyClass
object.One disadvantage with the design of the
clone
method is that the return type of clone
is Object
, and needs to be explicitly cast back into the appropriate type. However, overriding clone
to return the appropriate type is preferable and eliminates the need for casting in the client.Another disadvantage is that one often cannot access the
clone
method on an abstract type. Most interfaces and abstract classes in Java do not specify a public clone
method. As a result, often the clone
method can only be used if the actual class of an object is known, which is contrary to the abstraction principle of using the most generic type possible. For example, if one has a List
reference in Java, one cannot invoke clone
on that reference because List
specifies no public clone
method. Actual implementations of List
like ArrayList
and LinkedList
all generally have clone
methods themselves, but it is inconvenient and bad abstraction to carry around the actual class type of an object.Alternatives
There are alternatives toclone
, notably the use of a copy constructor - a constructor that accepts as a parameter another instance of the same class - or a factory method. These methods are not always adequate when the concrete type of the cloned object is not known in advance. is often not adequate either for the same reason, as most abstract classes do not implement a public clone
method.)Also the use of serialization and deserialization is an alternative to using clone.
Singleton pattern
When writing a class using the Singleton pattern, only one instance of that class can exist at a time. As a result, the class must not be allowed to make a clone. To prevent this, one can override theclone
method using the following code:public Object clone throws CloneNotSupportedException
This is only necessary if a superclass implements a public
clone
method, or to prevent a subclass from using this class's clone
method to obtain a copy. Classes don't usually inherit a public clone
method because Object
doesn't have a public clone
method, so it is usually unnecessary to explicitly implement a non-functional clone
method.Class hierarchy
To provide a properly cloneable object of any type, the clone method must be both declared correctly and implemented correctly according to the convention described in Object.clone.1) Every type that needs to be cloned must have a public clone method in its own class or a publicly accessible clone method in one of its parent classes.
Example:
To invoke clone on varY1, which is of type Y, then Y or a parent of Y must declare a publicly accessible clone method. Here, it is the parent class X that provides the public clone method.
public class X implements Cloneable
public class Y extends X
public class Z extends Y
public class test1
2) Every class that implements clone should call super.clone to obtain the cloned object reference. If the class has any object references that must be cloned as well, then the clone method should perform any required modifications on the object before returning it.
Example:
Since class Z contains an object reference, its clone method also clones that object reference in order to return a deep copy of the original.
public class X implements Cloneable
public class Y extends X
public class ObjectABC implements Cloneable
public class Z extends Y
public class test1
Pitfalls
If every class in a hierarchy implements aclone
method, all of these functions will be called upon cloning, adding some overhead. Over many iterations, this overhead could become significant.With complex object graphs, deep copying can also become problematic when recursive references exist.
It is not always appropriate to have multiple copies of the same object floating around. If the purpose of a specific
clone
implementation is not fully understood by consumers, it may unintentionally break the "single object, multiple references" paradigm.Final fields
Generally,clone
is incompatible with final
fields. Because clone
is essentially a default constructor it is impossible to assign a final
field within a clone
method; a compiler error is the result. Where the value of the field is an immutable object this is okay; just let the 'constructor' copy the reference and both the original and its clone will share the same object.But where the value is a mutable object it must be deep copied. One solution is to remove the
final
modifier from the field, giving up the benefits the modifier conferred.For this reason, some programmers suggest to make the objects in the hierarchy Serializable, and create copies by serializing the old object and then creating a new object from the resulting bitstream, which handles final data members correctly, but is significantly slower.
Alternatively, one can return a completely new object from the current objects fields, which can be done first calling the constructor, and later assigning non final fields. Another alternative method is actually making the idea formal : creating a copy constructor that takes an instance. In fact that is what is recommended over clone by some people.