Reputation: 77
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
Reputation: 56
In the code that you provided the sequence of steps are like below.
A
with i
value as 111
so a cloned object with same value i.e. 111
is created.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
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
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:
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
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
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