考虑下面的代码:

DummyBean dum = new DummyBean();
dum.setDummy("foo");
System.out.println(dum.getDummy()); // prints 'foo'

DummyBean dumtwo = dum;
System.out.println(dumtwo.getDummy()); // prints 'foo'

dum.setDummy("bar");
System.out.println(dumtwo.getDummy()); // prints 'bar' but it should print 'foo'

所以,我想把dumm复制到dum2,在不影响dum2的情况下改变dumm。但是上面的代码并没有这样做。当我改变了dumm中的一些东西,同样的变化也会发生在dum2中。

我想,当我说dumtwo = dum时,Java只复制了引用。那么,有没有办法创建一个新的dum副本并将其分配给dumtwo呢?


当前回答

这里有一个关于clone()的合理解释,如果你最终需要它…

这里:克隆(Java方法)

其他回答

是的,您只是对对象进行了引用。如果对象实现了可克隆,则可以克隆该对象。

查看这篇关于复制对象的wiki文章。

参考这里:对象复制

基本:Java对象复制。

让我们假设一个对象——obj1,它包含两个对象,containedObj1和containedObj2。

浅复制: 浅复制创建同一个类的新实例,并将所有字段复制到新实例并返回它。类提供了克隆方法,并提供了对浅复制的支持。

深复制: 当对象与其引用的对象一起复制时,就会发生深度复制。下图显示obj1在深度复制后被执行。不仅obj1被复制了,它包含的对象也被复制了。我们可以使用Java对象序列化来进行深度复制。不幸的是,这种方法也有一些问题(详细的示例)。

可能的问题: 克隆是很难正确实现的。 最好使用防御性复制、复制构造函数(如@egaga reply)或静态工厂方法。

If you have an object, that you know has a public clone() method, but you don’t know the type of the object at compile time, then you have problem. Java has an interface called Cloneable. In practice, we should implement this interface if we want to make an object Cloneable. Object.clone is protected, so we must override it with a public method in order for it to be accessible. Another problem arises when we try deep copying of a complex object. Assume that the clone() method of all member object variables also does deep copy, this is too risky of an assumption. You must control the code in all classes.

例如,org.apache.commons.lang.SerializationUtils将有使用序列化进行深度克隆的方法(源代码)。如果我们需要克隆Bean,那么在org.apache.commons.beanutils (Source)中有两个实用程序方法。

cloneBean将基于可用的属性getter和setter克隆一个bean,即使bean类本身没有实现Cloneable。 copyProperties将在所有属性名称相同的情况下,将属性值从源bean复制到目标bean。

public class MyClass implements Cloneable {

private boolean myField= false;
// and other fields or objects

public MyClass (){}

@Override
public MyClass clone() throws CloneNotSupportedException {
   try
   {
       MyClass clonedMyClass = (MyClass)super.clone();
       // if you have custom object, then you need create a new one in here
       return clonedMyClass ;
   } catch (CloneNotSupportedException e) {
       e.printStackTrace();
       return new MyClass();
   }

  }
}

在你的代码中:

MyClass myClass = new MyClass();
// do some work with this object
MyClass clonedMyClass = myClass.clone();

您可以尝试实现Cloneable并使用clone()方法;但是,如果你使用clone方法,你应该——按照标准——总是覆盖Object的公共Object clone()方法。

除了显式复制,另一种方法是使对象不可变(没有set或其他mutator方法)。这样问题就不会出现了。对于较大的对象,不变性变得更加困难,但另一方面,它推动你朝着分裂成连贯的小对象和复合对象的方向发展。