travolta andersson
travolta andersson

Reputation: 77

Java Clone Inheritance Example

This clone example confuses me. I don't understand how the first two outputs can be: 111 and 222 instead of: 222 and 222. Doesn't this "a2 = (A) a1.clone();" line mean that a2 becomes the same as a1?

code:

public class Main {

    public static void main(String[] args) {
    A a1 = new A();
    A a2;
    B b1 = new B();
    B b2;

    a2 = (A) a1.clone();
    a2.setI(222);

    // Why the different output?
    System.out.println("a1 = " + a1 + " a1.i " + a1.getI()); // i = 111
    System.out.println("a2 = " + a2 + " a2.i " + a2.getI()); // i = 222

    b2 = (B) b1.clone();

    b2.setI(888); 
    b2.setJ(999); 

    System.out.println("b1 = " + b1 + " b1.i " + b1.getI() + " b1.j " +      b1.getJ());
    System.out.println("b2 = " + b2 + " b2.i " + b2.getI() + " b2.j " + b2.getJ()); 
}
}

public class A implements Cloneable {
    private int i = 111;
    @Override
    public Object clone() {
        try {
            A a = (A) super.clone();
            return a;
        } catch (CloneNotSupportedException e) {
            throw new InternalError();
        }
    }
    public int getI() {
        return i;
    }

    public void setI(int i) {
        this.i = i;
        }
    }

    public class B extends A {
    private int j = 222;

    @Override
    public Object clone() {  
        Object o = super.clone();               
        B b = (B) o;
        return b;
    }

    public int getJ() {
        return j;
    }

    public void setJ(int j) {
        this.j = j;
    }
}

Upvotes: 3

Views: 5303

Answers (5)

user2290411
user2290411

Reputation: 56

In the code that you provided the sequence of steps are like below.

  1. Cloned the object A with i value as 111 so a cloned object with same value i.e. 111 is created.
  2. Then you changed the value of i to 222 for the original object so the value of cloned object is not updated as in cloning for primitive types new instances with same value (when the object is cloned) is created.

Upvotes: 0

user2030471
user2030471

Reputation:

From the documentation, Object.clone:

Creates and returns a copy of this object. The precise meaning of "copy" may depend on the class of the object. The general intent is that, for any object x, the expression:

x.clone() != x

will be true.

Continuing from the same document:

This method creates a new instance of the class of this object and initializes all its fields with exactly the contents of the corresponding fields of this object, as if by assignment; the contents of the fields are not themselves cloned. Thus, this method performs a "shallow copy" of this object, not a "deep copy" operation.

Upvotes: 0

ach
ach

Reputation: 6234

Clone only makes a "shallow" copy of the object, meaning that the primitive values and object references are copied. What you want (I'm assuming) is a "deep" copy, where referenced objects themselves are cloned. A few of the most popular ways to do this:

  • Java Deep Cloning Library
  • Serialize the object, and then de-serialize it (warning: this is slow!)
  • Implement clone() in all of the referenced objects, and call clone() on these objects in the referencing object's clone() method. You can also use a copy constructor in a similar manner.

Upvotes: 2

kaysush
kaysush

Reputation: 4836

No they don't point to same object anymore and hence value change of a2 doesn't affect the a1 object. That's the concept of clone() you get a same but distinct copy of the object.

When you do this

a1=(A)a2.clone();

you get a completely new object , independent of the object from which it is copied.

Upvotes: 2

Chris Knight
Chris Knight

Reputation: 25074

The values get copied across in a clone() operation, but you end up with 2 distinct objects, just that they have the same values.

a2 = (A) a1.clone()

creates a new object, entirely seperate to a1. But the internal state of a1 has been replicated into a2. Therefore, changing a2 has no effect on a1 (if the cloning is done properly!)

Upvotes: 5

Related Questions