考虑下面的代码:

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


当前回答

使用Kotlin扩展函数

fun <T : Any?> T.duplicate(): T? {
    var copyObject: T? = null
    try {
        val byteArrayOutputStream = ByteArrayOutputStream()
        val objectOutputStream = ObjectOutputStream(byteArrayOutputStream)
        objectOutputStream.writeObject(this)
        objectOutputStream.flush()
        objectOutputStream.close()
        byteArrayOutputStream.close()
        val byteData = byteArrayOutputStream.toByteArray()
        val byteArrayInputStream = ByteArrayInputStream(byteData)
        try {
            copyObject = ObjectInputStream(byteArrayInputStream).readObject() as T
        } catch (e: ClassNotFoundException) {
            e.printStackTrace()
        }
    } catch (e: IOException) {
        e.printStackTrace()
    }
    return copyObject
}

用例

var object = Any()
var duplicateObject = object.duplicate()

Java

<T extends Object> T copyObject(T sourceObject) {

    T copyObject = null;

    try {
        ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
        ObjectOutputStream objectOutputStream = new ObjectOutputStream(byteArrayOutputStream);
        objectOutputStream.writeObject(sourceObject);
        objectOutputStream.flush();
        objectOutputStream.close();
        byteArrayOutputStream.close();
        byte[] byteData = byteArrayOutputStream.toByteArray();
        ByteArrayInputStream byteArrayInputStream = new ByteArrayInputStream(byteData);
        try {
            copyObject = (T) new ObjectInputStream(byteArrayInputStream).readObject();
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }
    } catch (IOException e) {
        e.printStackTrace();
    }
    return copyObject;
}

用例

Object object = new Object();
Object duplicateObject = copyObject(object);

==============================================

芬兰湾的科特林更新

如果您使用数据类,那么您将有复制方法来复制Kotlin数据类。很酷的是,你还可以通过一些值来修改对象的新副本。我推荐这种方式。

例子:

/ /类

data class TestModel(val title: String, var subtitle: String)

用例

val testClass = TestModel("Test title", "Test subtitle")

val newInstance = testClass.copy(subtitle = "new subtitle for copy instance")

其他回答

请按照以下步骤进行:

public class Deletable implements Cloneable{

    private String str;
    public Deletable(){
    }
    public void setStr(String str){
        this.str = str;
    }
    public void display(){
        System.out.println("The String is "+str);
    }
    protected Object clone() throws CloneNotSupportedException {
        return super.clone();
    }
}

无论你想要得到另一个对象,简单地执行克隆。 例句:

Deletable del = new Deletable();
Deletable delTemp = (Deletable ) del.clone(); // this line will return you an independent
                                 // object, the changes made to this object will
                                 // not be reflected to other object

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

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

参考这里:对象复制

使用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);

注意:性能要慢得多。

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

dumtwo = dum.copy();

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

深度克隆是您的答案,它需要实现Cloneable接口并重写clone()方法。

public class DummyBean implements Cloneable {

   private String dummy;

   public void setDummy(String dummy) {
      this.dummy = dummy;
   }

   public String getDummy() {
      return dummy;
   }

   @Override
   public Object clone() throws CloneNotSupportedException {
      DummyBean cloned = (DummyBean)super.clone();
      cloned.setDummy(cloned.getDummy());
      // the above is applicable in case of primitive member types like String 
      // however, in case of non primitive types
      // cloned.setNonPrimitiveType(cloned.getNonPrimitiveType().clone());
      return cloned;
   }
}

你会这样称呼它 DummyBean dumtwo = dumm .clone();