Cool Penguin

Simple developer guides

Java

More

on CoolPenguin.net:

Clone Java objects

Since objects in Java are manipulated through reference variables, there is no direct way to copy an object. Classes that want copying functionality must implement clone() method to do so. This guide shows how to make a Java class Cloneable and perform cloning.

A class to be cloned:

class Person {
    private String firstName;
    private String lastName;

    private Person assistant;

    public Person(String firstName, String lastName) {
        this.firstName = firstName;
        this.lastName = lastName;
    }

    public void setAssistant(Person assistant) {
        this.assistant = assistant;
    }
	
	public Person getAssistant() {
		return assistant;
	}
}

Todos:

Our cloneable class:

class Person implements Cloneable {
    private String firstName;
    private String lastName;

    private Person assistant;

    public Person(String firstName, String lastName) {
        this.firstName = firstName;
        this.lastName = lastName;
    }

    public void setAssistant(Person assistant) {
        this.assistant = assistant;
    }

    public Person getAssistant() {
        return assistant;
    }

    public Object clone() throws CloneNotSupportedException {
        Person cloned = (Person) super.clone();

        /*
		If we don't do anything else, the cloned person 
		will refer to the to the same assistant object 
		as the original person.

		In this example we want to avoid that and make a real copy
		of the assistant object as well.
          */
        if (this.assistant != null)
            cloned.assistant = (Person) this.assistant.clone();
        return cloned;
    }
}

Note: deep copying can be risky if there is a circular reference as it can produce an endless loop of cloning. Those cases need special attention. In this concrete example it's not a problem, we assumed that the "assistant" relationship is not reflexive.

How to clone:

public class Test {
    public static void main(String[] args) {
        try {
            Person john = new Person("John", "Doe");
            Person bob = new Person("Bob", "Gombocki");
            john.setAssistant(bob);
            Person johnsClone = (Person) john.clone();
            System.out.println("John is cloned: " + (john != johnsClone));
            System.out.println("John's assistant, Bob is cloned: " + (john.getAssistant() != johnsClone.getAssistant()));
        } catch (CloneNotSupportedException e) {
            e.printStackTrace();
        }
    }
}

To Clone or NOT to Clone

This article focused on how to use object cloning to copy objects. But it's important to know its flaws - discussed in greater detail by Josh Bloch - and understand why it's usually not the right thing to do.

I also recommend Venkat Subramaniam's article on copy constructors, and how to use them in conjunction with cloning.

3 comments:
shahzad bhatti - 2009-10-15 10:36:46
This is good example on how to implement cloning however Java cloning is broken and not recommended. Read Effective Java for more details or read Josh Bloch's comments from http://www.artima.com/intv/bloch13.html.
James - 2009-10-15 12:00:15
I've always coded on the assumption that if I have to implement a clone() method, I'm doing something wrong. Esp because in many languages it's considered taboo to even consider touching a Cloneable interface
bob - 2009-10-15 14:28:17
This short guide was made to be a simple introduction for developers who are unfamiliar with the concept of cloning.

Of course cloning in itself is often not by any means the best way to copy objects, but I wouldn't say it can't have some sensible uses.

Exposing a public copy constructor has its own risks and drawbacks too.

I like the idea of using these two methods in conjunction to cover up each others shortcomings:

http://www.agiledeveloper.com/articles/cloning072002.htm
Your name

Your comment