考虑下面的代码:

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方法)

其他回答

为什么使用反射API没有答案?

private static Object cloneObject(Object obj){
        try{
            Object clone = obj.getClass().newInstance();
            for (Field field : obj.getClass().getDeclaredFields()) {
                field.setAccessible(true);
                field.set(clone, field.get(obj));
            }
            return clone;
        }catch(Exception e){
            return null;
        }
    }

这真的很简单。

EDIT:通过递归包含子对象

private static Object cloneObject(Object obj){
        try{
            Object clone = obj.getClass().newInstance();
            for (Field field : obj.getClass().getDeclaredFields()) {
                field.setAccessible(true);
                if(field.get(obj) == null || Modifier.isFinal(field.getModifiers())){
                    continue;
                }
                if(field.getType().isPrimitive() || field.getType().equals(String.class)
                        || field.getType().getSuperclass().equals(Number.class)
                        || field.getType().equals(Boolean.class)){
                    field.set(clone, field.get(obj));
                }else{
                    Object childObj = field.get(obj);
                    if(childObj == obj){
                        field.set(clone, clone);
                    }else{
                        field.set(clone, cloneObject(field.get(obj)));
                    }
                }
            }
            return clone;
        }catch(Exception e){
            return null;
        }
    }

你可以从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));

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

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

dumtwo = dum.copy();

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

在包中导入org.apache.commons.lang.SerializationUtils;有一种方法:

SerializationUtils.clone(Object);

例子:

this.myObjectCloned = SerializationUtils.clone(this.object);

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

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

参考这里:对象复制