Implementing clone()
Home ] Up ] The clone() method ] [ Implementing clone() ] The Cloneable Interface ] Fixing Shallow Copies ]

 

 

Since you can't call the Object class's clone() method directly, you might think that you could implement your own clone method in your class, and then have it call the Object class's clone() method.

So let's try that:

public class CloneMe
{
  // Constructor
  public CloneMe(Object object, int value)
  {
    m_object = object;
    m_value = value;
  }
  
  public void print()
  {
    System.out.println("---CloneMe object---\n" + 
                       "Object:  " + m_object + 
                       "Value:   " + m_value);
  }
  
  public Object clone()
  {
    return super.clone();
  }
  
  ///// Private data /////
  private Object m_object;
  private int m_value;
}

However, when we try to compile this code, the Java compiler produces the following compile-time error:

"CloneMe.java": unreported exception java.lang.CloneNotSupportedException; 
     must be caught or declared to be thrown at line 18, column 23

It turns out that the clone method is declared as follows:

protected Object clone() throws CloneNotSupportedException

So we have to modify our clone() method to conform to the Object class's signature:

public class CloneMe
{
  // Constructor
  public CloneMe(Object object, int value)
  {
    m_object = object;
    m_value = value;
  }
  
  public void print()
  {
    System.out.println("---CloneMe object---\n" + 
                       "Object:  " + m_object + 
                       "Value:   " + m_value);
  }
  
  public Object clone() throws CloneNotSupportedException
  {
    return super.clone();
  }
  
  ///// Private data /////
  private Object m_object;
  private int m_value;
}

Now it compiles!

So let's test it:

class MyObject
{
  public MyObject(String name)
  {
    m_name = name;
  }

  public String toString()
  {
    return "HashId: " + super.toString() + "\n" +
           "Name: " + m_name + "\n";
  }

  //// Data ////
  private String m_name;
}

public class CloneMeTest
{
  public static void main(String[] args) 
                  throws CloneNotSupportedException
  {
    MyObject mo1 = new MyObject("Monkeys");
    CloneMe cm1 = new CloneMe(mo1, 27);
    cm1.print();
    CloneMe cm2 = (CloneMe) cm1.clone();
    cm2.print();
  }
}

Note that I had to add the throws CloneNotSupportedException to get the above to compile.  (This relates to the rules governing how exceptions are handled, which we haven't talked about yet.  Just take this change on faith, at least for the moment.)

OK, the above compiles.  What happens when we run it?  We get the following:

Exception in thread "main" java.lang.CloneNotSupportedException: CloneMe
	at java.lang.Object.clone(Native Method)
	at CloneMe.clone(CloneMe.java:18)
	at CloneMeTest.main(CloneMeTest.java:25)

What's wrong, now?

 

This page was last modified on 02 October, 2007