1

I'm trying to implement the clone of a derived class, but , I didn't get, I don't know why. Why can't I clone the class B?, I get an CastClassExpcetion.

public class A implements Cloneable {
    private Integer a;

    @Override
    protected Object clone() throws CloneNotSupportedException {
        A clone = new A(); //Why if I do this instance of super.clone() I get an exception?
        A clone = (A) super.clone();
        clone.a = this.a;
        return clone;
    }
      ..

}

public class B extends A implements Cloneable {
    private String b;
..
    @Override
    protected Object clone() throws CloneNotSupportedException {

        B clone = (B) super.clone();
        clone.b = this.b;
        return clone;
    }

    public static void main(String[] args) throws CloneNotSupportedException {
        B b = new B(1, "s");
        B clone = b.clone();                
    }

}
Guille
  • 2,248
  • 3
  • 24
  • 42
  • 2
    related: http://stackoverflow.com/questions/4081858/about-java-cloneable – mariusm Sep 05 '14 at 06:33
  • By seeing your code (in special your clone implementation and your main-method), i do think that you dont know what you are doing. What do you want to archieve? Why `System.out.println("A");`? – Ben Sep 05 '14 at 07:39
  • Well, it was just for knowing the code had ended. – Guille Sep 05 '14 at 08:12

2 Answers2

0

You are mistakenly returning a and b in your clone() methods. This causes an exception in B.clone(), since you can't cast an integer to a B.

To fix, just ensure you return your clone variable instead.


Also note that fields values are automatically copied to your clone object. There is no need to assign field values to your clone, unless they are mutable and you wish to defensively copy them. In your clone methods, you have these redundant lines:

clone.a = this.a;

and

clone.b = this.b;

You can remove both lines from your B.clone() method, since strings and integers are immutable.

Duncan Jones
  • 67,400
  • 29
  • 193
  • 254
  • When I do A clone = (A) super.clone();, Shouldn't I do A clone = new A(); and then I get an CastClassException? Because if I do super.clone(), am I not working with the same reference? and that's not a clone. Or it looks like when I debug the code. – Guille Sep 05 '14 at 06:58
0

You will get a ClassCastException, because A != B
By calling super.clone() (in object B), you will get a object of A. (because super is A)
But object of A cannot be casted to B!
(A is not child of B, but B is child of A)

I other simplier words:
B is/contains more than A (it extends A!)
So, you cannot cast A to B, because A is missing the B part! (and this is needed to have an object of B!)
On the other side, you can cast B to A, because B contains A.

@Override
protected Object clone() throws CloneNotSupportedException {

    B clone = (B) super.clone(); //here is the problem! A is not (cannot be casted to) B.
    clone.b = this.b;
    return clone;
}

You cannot cast Car to Porsche (it is more than just a car), but you can cast Porsche to Car.

Ben
  • 3,378
  • 30
  • 46