Jump to content

Clone (Java method)

From Alfawiki
Adapted from the English Wikipedia article Clone (Java method), available under CC BY-SA 4.0Updated 9 August 2025
clone()
Company typeMethod
IndustryProgramming / Software Development
ProductsObject duplication in Java

clone() is a method within the Java programming language designed for duplicating objects. Because Java handles objects through references and does not include a direct copy operator, clone() supplies this critical capability.

Overview

To enable object copying, classes need to implement a mechanism, commonly by utilizing "Object.clone()".

The clone() method acts similarly to a copy constructor, usually calling the superclass’s clone() method recursively until it reaches the version defined in Object. The root class Object provides a built-in facility for creating object duplicates.

The clone() method in Object generates and returns a new instance of the same class with identical field values. Nevertheless, it raises a CloneNotSupportedException unless the class implements the marker interface Cloneable.

By default, the cloning performed by Object.clone() is a shallow copy. For scenarios requiring deep copy or specific cloning logic, subclasses must override clone(), typically invoking the superclass method within their implementation.

Typical usage of clone() in Java appears as: <syntaxhighlight lang="java"> Object copy = obj.clone(); </syntaxhighlight> or <syntaxhighlight lang="java"> MyClass copy = (MyClass) obj.clone(); </syntaxhighlight> where an explicit cast converts the returned Object into the desired type.

One limitation is that clone() returns an Object, necessitating casting. Since J2SE 5.0, overriding with covariant return types can eliminate this requirement.

Another issue involves restricted accessibility for abstract types. Most Java interfaces and abstract classes do not expose a public clone(), so cloning requires knowledge of the concrete class. For instance, although implementations like ArrayList and LinkedList provide clone(), a reference declared as List cannot call it—complicating abstraction and type handling.

Alternatives

Options besides clone() include employing a copy constructor—a constructor that accepts an instance of the same class—or using a factory method. These alternatives may be insufficient when the precise runtime type of the object to be copied is unknown. Likewise, clone()'s utility is limited because most abstract classes do not offer a public cloning method.

Serialization combined with deserialization also represents another approach for object copying.

Singleton pattern

Within the context of the Singleton pattern, where only one instance of a class should exist, cloning must be explicitly disabled. This is achieved by overriding clone() to throw an exception:

<syntaxhighlight lang="java"> public Object clone() throws CloneNotSupportedException {

   throw new CloneNotSupportedException();

} </syntaxhighlight>

This override is essential if any superclass provides a public clone(), or to prevent subclasses from enabling cloning. Since Object's own clone() is not publicly accessible, explicit blocking is often unnecessary.

Class hierarchy

For cloning to function correctly, the clone() method must be properly declared and implemented following the conventions outlined in Object.clone().

1) Any type that supports cloning must have a publicly accessible clone() method either within its own class or inherited from a superclass.

Illustration: When calling clone() on an instance varY1 of type Y, it is necessary that class Y or one of its ancestors declares a public clone(). In this case, the superclass X fulfills that requirement:

<syntaxhighlight lang="java"> public class X implements Cloneable {

   public X clone() throws CloneNotSupportedException {
       return (X) super.clone();
   }

}

public class Y extends X { }

public class Z extends Y { }

public class test1 {

   public void function() throws CloneNotSupportedException {
       Y varY1 = new Z();
       Y varY2 = (Y) varY1.clone();
   }

} </syntaxhighlight>

2) When overriding clone(), it is standard practice to invoke super.clone(). To achieve a deep copy, any mutable fields referencing other objects should themselves be cloned inside the clone() method, thereby preventing shared mutable data between the original and the duplicate.

Example: The class Z performs deep cloning by duplicating its referenced object:

<syntaxhighlight lang="java"> public class X implements Cloneable {

   public X clone() throws CloneNotSupportedException {
       return (X) super.clone();
   }

}

public class Y extends X { }

public class ObjectABC implements Cloneable {

   public ObjectABC clone() throws CloneNotSupportedException {
       return (ObjectABC) super.clone();
   }

}

public class Z extends Y {

   private ObjectABC someABC;
   public Z clone() throws CloneNotSupportedException {
       Z newZ = (Z) super.clone();
       newZ.someABC = someABC.clone();
       return newZ;
   }

}

public class test1 {

   public void function() throws CloneNotSupportedException {
       Y varY1 = new Z();
       Y varY2 = (Y) varY1.clone();
   }

} </syntaxhighlight>

Pitfalls

Adding a clone() implementation in every class within an inheritance chain can introduce performance costs, especially when cloning occurs frequently. Deep copying complex object structures is further complicated by recursive references.

Misusing the clone() method can lead to multiple instances of what should logically be a single object, violating the principle of "one object, multiple references" and potentially causing unintended behavior.

Final fields

The clone() mechanism generally conflicts with final fields because it mimics a default constructor call, which does not allow reassignment of final variables and results in compilation errors. Immutable objects can safely share references, but mutable objects require deep copies, often forcing developers to remove the final modifier and lose its associated benefits.

One approach to address this limitation involves making objects Serializable and performing cloning through serialization, which respects final fields but at the cost of slower execution. Alternatively, employing constructors—such as copy constructors that accept an existing instance to produce a duplicate—is frequently favored over clone(), offering greater clarity and control.

References


External links