这个克隆示例让我很困惑。我不明白前两个输出是怎样的:111和222而不是:222和222。 这不是“a2 =(A)a1.clone();” line是指a2与a1相同?
代码:
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;
}
}
答案 0 :(得分:5)
这些值会在clone()
操作中被复制,但最终会有2个不同的对象,只是它们具有相同的值。
a2 = (A) a1.clone()
创建一个新对象,完全独立于a1。但是a1的内部状态已被复制到a2中。因此,更改a2对a1没有影响(如果克隆正确完成!)
答案 1 :(得分:2)
不,他们不再指向同一个对象,因此a2
的值更改不会影响a1
对象。这就是clone()
的概念,你得到的是对象的相同但不同的副本。
当你这样做时
a1=(A)a2.clone();
你得到一个全新的对象,与复制它的对象无关。
答案 2 :(得分:2)
克隆只生成对象的“浅”副本,这意味着复制了原始值和对象引用。你想要的(我假设)是一个“深层”副本,其中引用的对象本身是克隆的。一些最流行的方法:
clone()
,并在引用对象的clone()
方法中对这些对象调用clone()
。您也可以以类似的方式使用复制构造函数。答案 3 :(得分:0)
从文档中Object.clone
:
创建并返回此对象的副本。的确切含义 “复制”可能取决于对象的类别。一般意图是 对于任何对象x,表达式为:
x.clone() != x
将是真的。
继续使用同一份文件:
此方法创建此对象的类的新实例 准确地初始化其所有字段的内容 该对象的相应字段,好像通过赋值;内容 这些田地本身没有克隆。因此,该方法执行a 这个对象的“浅拷贝”,而不是“深拷贝”操作。
答案 4 :(得分:0)
在您提供的代码中,步骤顺序如下所示。
A
的对象克隆为i
111
,以便创建具有相同值的克隆对象,即111
。i
值更改为222
,因此克隆对象的值不会更新,就像克隆原始类型具有相同值的新实例一样(克隆对象时) )已创建。