Как мне скопировать объект в Java? - PullRequest
737 голосов
/ 15 мая 2009

Рассмотрим код ниже:

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'

Итак, я хочу скопировать dum в dumtwo и изменить dum, не затрагивая dumtwo. Но код выше не делает этого. Когда я что-то изменяю в dum, то же самое происходит и в dumtwo.

Полагаю, когда я говорю dumtwo = dum, Java копирует только ссылку . Итак, есть ли способ создать новую копию dum и присвоить ее dumtwo?

Ответы [ 21 ]

10 голосов
/ 15 мая 2009

Вот приличное объяснение clone(), если вам это понадобится ...

Здесь: клон (метод Java)

8 голосов
/ 23 октября 2011

Используйте утилиту глубокого клонирования:

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

Это позволит глубоко скопировать любой объект Java, проверьте его на https://github.com/kostaskougios/cloning

7 голосов
/ 08 июля 2014

Глубокое клонирование - это ваш ответ, который требует реализации интерфейса 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, 
      // however, in case of non primitive types
      // cloned.setNonPrimitiveType(cloned.getNonPrimitiveType().clone());
      return cloned;
   }
}

Вы будете называть это так DummyBean dumtwo = dum.clone();

6 голосов
/ 15 мая 2009

Для этого вам нужно каким-то образом клонировать объект. Хотя в Java есть механизм клонирования, не используйте его, если это не нужно. Создайте метод копирования, который работает для вас, а затем выполните:

dumtwo = dum.copy();

Здесь - еще несколько советов по различным методам выполнения копирования.

5 голосов
/ 15 мая 2009

Кроме явного копирования, другой подход - сделать объект неизменным (без set или других методов-мутаторов). Таким образом, вопрос никогда не возникает. Неизменяемость становится более сложной для более крупных объектов, но другой стороной этого является то, что она толкает вас в направлении разделения на когерентные мелкие объекты и композиты.

3 голосов
/ 02 марта 2014
class DB {
  private String dummy;

  public DB(DB one) {
    this.dummy = one.dummy; 
  }
}
2 голосов
/ 04 февраля 2018
public class MyClass implements Cloneable {

private boolean myField= false;
// and other fields or objects

public MyClass (){}

@Override
public MyClass clone() throws CloneNotSupportedException {
   try
   {
       MyClass clonedMyClass = (MyClass)super.clone();
       // if you have custom object, then you need create a new one in here
       return clonedMyClass ;
   } catch (CloneNotSupportedException e) {
       e.printStackTrace();
       return new MyClass();
   }

  }
}

и в вашем коде:

MyClass myClass = new MyClass();
// do some work with this object
MyClass clonedMyClass = myClass.clone();
2 голосов
/ 23 декабря 2014

Передайте объект, который вы хотите скопировать, и получите нужный объект:

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 на нужный объект.

Счастливого кодирования!

2 голосов
/ 25 июля 2011

Вы можете выполнять глубокое копирование автоматически с помощью XStream из http://x -stream.github.io / :

XStream - это простая библиотека для сериализации объектов в XML и обратно еще раз.

Добавьте его в свой проект (если используете maven)

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

Тогда

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

С этим у вас есть копия без необходимости реализации какого-либо интерфейса клонирования.

1 голос
/ 05 февраля 2017

Если вы можете добавить аннотацию к исходному файлу, можно использовать процессор аннотаций или генератор кода, например , этот .

import net.zerobuilder.BeanBuilder

@BeanBuilder
public class DummyBean { 
  // bean stuff
}

Будет сгенерирован класс DummyBeanBuilders, который имеет статический метод dummyBeanUpdater для создания мелких копий, так же, как вы делаете это вручную.

DummyBean bean = new DummyBean();
// Call some setters ...
// Now make a copy
DummyBean copy = DummyBeanBuilders.dummyBeanUpdater(bean).done();
...