2012-03-22 89 views
1

我试图克隆一个对象并更改新克隆对象的成员函数。如果是浅拷贝,并且根据wiki页面,浅拷贝和原始对象指向同一个对象,则应该更改变量值。对象克隆浅拷贝不会改变变量

CloneExample obj1=new CloneExample(); 
    CloneExample obj2=(CloneExample) obj1.clone(); 
    obj1.a=2; 
    obj1.c='a'; 
    System.out.println("obj1 real "+obj1.a+" "+obj1.c); 
    System.out.println("obj2 real "+obj2.a+" "+obj2.c); 
    obj2.a=99; 
    obj2.c='z'; 
    System.out.println("obj2 after change "+obj2.a+" "+obj2.c); 
    System.out.println("obj1 after change "+obj1.a+" "+obj1.c); 
    System.out.println("obj1="+obj1+" obj2="+obj2); 

如果这个克隆是浅拷贝,然后OBJ2和OBJ1指向相同的参考OBJ,改变OBJ2应OBJ1反映。它不会发生。任何人都可以解释(我明白克隆旨在给​​我们对象的副本,但如果它是浅拷贝,那么为什么我们需要浅拷贝?我们应该总是去深拷贝)。 谢谢。

回答

0

当你调用object.clone(),将创建新的对象。因此,您可以参考此对象。只有原始类型字段的对象完全克隆。因此,您可以从obj1副本中获得完全独立。但是如果你的对象有引用的字段,你需要做一个深层次的克隆。

+1

您只需要深入克隆指向可变对象的引用字段即可。例如,一个字符串字段是一个引用,但不需要深入克隆。 – 2012-03-22 21:11:19

3

为什么你认为克隆是一个浅拷贝?看到这里:http://docs.oracle.com/javase/6/docs/api/java/lang/Object.html#clone()

正如它所说 - 什么克隆做是依赖于实现。此外,“浅拷贝”不会简单地创建对同一对象的新引用 - 通常这意味着使用与从中复制的对象相同的内部成员创建新实例。但是,如果您更改新obj的成员变量以指向新的东西,则不会更改原始obj的成员变量。

3

obj1的浅拷贝为您的CloneExample类(obj1!= obj2)创建另一个实例 obj2。 他们不共享价值成员。

但是,如果我们的类包含引用类型,例如java.util.Date,然后改变它的值将在两个物体反射如果它们共享参照该java.util.Date

In Java, what is a shallow copy?

+1

'java.lang.Integer'是一个不好的例子,因为它是不可变的。以'java.util.Date'为例。 – madth3 2012-03-22 20:39:46

+0

@ madth3你说得对,谢谢指出! – surfen 2012-03-22 20:46:54