考虑下面的代码:

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


当前回答

我使用谷歌的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;
}
}

其他回答

使用深度克隆工具:

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

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

要做到这一点,你必须以某种方式克隆对象。虽然Java有克隆机制,但如果没有必要就不要使用它。创建一个复制方法,为你做复制工作,然后做:

dumtwo = dum.copy();

这里有一些关于完成副本的不同技巧的建议。

你可以从http://x-stream.github.io/:用XStream自动深度复制

XStream是一个简单的库,用于将对象序列化为XML和反向 一次。

将其添加到项目中(如果使用maven)

<dependency>
    <groupId>com.thoughtworks.xstream</groupId>
    <artifactId>xstream</artifactId>
    <version>1.3.1</version>                
</dependency>

Then

DummyBean dum = new DummyBean();
dum.setDummy("foo");
DummyBean dumCopy = (DummyBean) XSTREAM.fromXML(XSTREAM.toXML(dum));

这样你就有了一个副本,而不需要实现任何克隆接口。

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

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

参考这里:对象复制

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

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解析为所需的对象。

编码快乐!