Home > OS >  Java class implements "clone()" but throws CloneNotSupportedException
Java class implements "clone()" but throws CloneNotSupportedException

Time:06-27

I've got code below, I expected that class My has overriden clone() function, it should work. But seems calling super.clone() throws out exception.

class My {
  @Override
  public My clone() {
    My ret = null;
    try {
      ret = (My)super.clone();
    } catch (CloneNotSupportedException e) {
      System.out.println("Should not reach here");
      e.printStackTrace();
    }
    return ret;
  }
}
public class UseClone implements Cloneable {
  public static void main(String[] args) {
    My nc = new My();
    My n2 = (My) nc.clone();
  }
}

It prints:

Should not reach here
java.lang.CloneNotSupportedException: mygroup.My
        at java.lang.Object.clone(Native Method)
        at mygroup.My.clone(UseClone.java:9)
        at mygroup.UseClone.main(UseClone.java:20)
        at org.codehaus.mojo.exec.ExecJavaMojo$1.run(ExecJavaMojo.java:254)
        at java.lang.Thread.run(Thread.java:748)

So how to make it work?

CodePudding user response:

You are cloning the My instance not the UseClone instance. Do class My implements Cloneable then it should be worked.

CodePudding user response:

You have defined a class "My" which has some issues. You have also defined UseClone, but it's only peripherally related so I'm leaving it out. Here is a stripped down class definition for My:

class My {
    @Override
    public My clone() {
        return super.clone();
    }
}

Trying to compile the My class from above results in the following error:

java: incompatible types: java.lang.Object cannot be converted to My

A few points about the code and the error:

  • You've called a method super.clone() where that method itself returns an object of type Object
  • That call (to super.clone()) does that because it resolves to Object.clone() which has this signature:
    protected Object clone() throws CloneNotSupportedException
    
  • The compiler is telling you that the return type from super.clone() (again, return type Object) isn't compatible with the return type you have defined in your method signature:
    public My clone() {
    

To fix your code:

  1. Modify the My class to implement the Cloneable interface, changing from this:

    class My {
    

    to this:

    class My implements Cloneable {
    
  2. Change the return type in your method so that it returns Object instead of My:

    class My implements Cloneable {
        public Object clone() {
            return super.clone();
        }
    }
    
  3. Add a throws clause to your clone() method, changing from this:

    public Object clone() {
    

    to this:

    public Object clone() throws CloneNotSupportedException {
    

In the end, here's a basic working version of My class:

class My implements Cloneable {
    public Object clone() throws CloneNotSupportedException {
        return super.clone();
    }
}

CodePudding user response:

The My calss should implement Cloneable

public class My implements Cloneable{
    public Object clone() throws CloneNotSupportedException {
        return super.clone();
    }
}
public class UseClone implements Cloneable{
    public static void main(String[] args) throws CloneNotSupportedException {
        My nc = new My();
        My n2 = (My) nc.clone();
    }
}
  • Related