考虑下面的代码:

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


当前回答

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

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

其他回答

使用gson复制对象。

public static <T>T copyObject(Object object){
    Gson gson = new Gson();
    JsonObject jsonObject = gson.toJsonTree(object).getAsJsonObject();
    return gson.fromJson(jsonObject,(Type) object.getClass());
}

假设我有一个客体人。所以

Person copyPerson = copyObject(person);

注意:性能要慢得多。

这也有用。假设模型

class UserAccount{
   public int id;
   public String name;
}

第一次添加 编译'com.google.code.gson:gson:2.8.1'到你的应用>gradle & sync。然后

Gson gson = new Gson();
updateUser = gson.fromJson(gson.toJson(mUser),UserAccount.class);

您可以通过在访问修饰符后使用瞬态关键字来排除使用字段。

注意:这是不好的做法。也不建议使用克隆或JavaSerialization,它是缓慢和坏的。为最佳性能参考写复制构造函数。

类似的

class UserAccount{
        public int id;
        public String name;
        //empty constructor
        public UserAccount(){}
        //parameterize constructor
        public UserAccount(int id, String name) {
            this.id = id;
            this.name = name;
        }

        //copy constructor
        public UserAccount(UserAccount in){
            this(in.id,in.name);
        }
    }

90000次迭代的测试数据: Line UserAccount clone = gson.fromJson(gson.toJson(aO), UserAccount.class);耗时808毫秒

Line UserAccount clone = new UserAccount(aO);耗时小于1毫秒

结论:如果你的老板很疯狂,而你喜欢速度,那就用gson吧。如果您喜欢质量,请使用第二个复制构造函数。

你也可以在Android Studio中使用复制构造函数代码生成器插件。

创建一个复制构造函数:

class DummyBean {
  private String dummy;

  public DummyBean(DummyBean another) {
    this.dummy = another.dummy; // you can access  
  }
}

每个对象都有一个clone方法,可以用来复制对象,但不要使用它。创建类和做不恰当的克隆方法太容易了。如果你打算这样做,至少要阅读Joshua Bloch在Effective Java中所讲的内容。

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

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

参考这里:对象复制

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