考虑下面的代码:

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呢?


当前回答

基本: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。

其他回答

class DB {
  private String dummy;

  public DB(DB one) {
    this.dummy = one.dummy; 
  }
}

使用深度克隆工具:

SomeObjectType copy = new Cloner().deepClone(someObject);

这将深度复制任何java对象,检查它在https://github.com/kostaskougios/cloning

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

这里:克隆(Java方法)

我使用谷歌的JSON库来序列化它,然后创建序列化对象的新实例。它进行深度复制,但有一些限制:

不能有任何递归引用 它不会复制不同类型的数组 数组和列表应该被类型化,否则它将找不到要实例化的类 您可能需要在自己声明的类中封装字符串

我还使用这个类来保存用户首选项,窗口和在运行时重新加载的东西。这是非常容易使用和有效的。

import com.google.gson.*;

public class SerialUtils {

//___________________________________________________________________________________

public static String serializeObject(Object o) {
    Gson gson = new Gson();
    String serializedObject = gson.toJson(o);
    return serializedObject;
}
//___________________________________________________________________________________

public static Object unserializeObject(String s, Object o){
    Gson gson = new Gson();
    Object object = gson.fromJson(s, o.getClass());
    return object;
}
       //___________________________________________________________________________________
public static Object cloneObject(Object o){
    String s = serializeObject(o);
    Object object = unserializeObject(s,o);
    return object;
}
}

传递你想要复制的对象并获取你想要的对象:

private Object copyObject(Object objSource) {
        try {
            ByteArrayOutputStream bos = new ByteArrayOutputStream();
            ObjectOutputStream oos = new ObjectOutputStream(bos);
            oos.writeObject(objSource);
            oos.flush();
            oos.close();
            bos.close();
            byte[] byteData = bos.toByteArray();
            ByteArrayInputStream bais = new ByteArrayInputStream(byteData);
            try {
                objDest = new ObjectInputStream(bais).readObject();
            } catch (ClassNotFoundException e) {
                e.printStackTrace();
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
        return objDest;

    }

现在将objDest解析为所需的对象。

编码快乐!