Как сделать глубокую копию объекта в Java? - PullRequest
271 голосов
/ 15 сентября 2008

В Java немного сложно реализовать функцию глубокого копирования объектов. Какие шаги вы предпринимаете, чтобы гарантировать, что исходный и клонированный объекты не имеют общего доступа?

Ответы [ 17 ]

8 голосов
/ 16 сентября 2008

Используйте XStream (http://x -stream.github.io / ). Вы даже можете контролировать, какие свойства вы можете игнорировать с помощью аннотаций или явного указания имени свойства для класса XStream. Более того, вам не нужно реализовывать клонируемый интерфейс.

7 голосов
/ 15 сентября 2008

Глубокое копирование может быть сделано только с согласия каждого класса. Если у вас есть контроль над иерархией классов, вы можете реализовать клонируемый интерфейс и реализовать метод Clone. В противном случае выполнение глубокого копирования невозможно сделать безопасно, поскольку объект также может совместно использовать ресурсы, не связанные с данными (например, соединения с базой данных). В целом, однако, глубокое копирование считается плохой практикой в ​​среде Java, и его следует избегать с помощью соответствующих методов проектирования.

6 голосов
/ 29 ноября 2016

Для сложных объектов и когда производительность незначительна, я использую библиотеку json, например gson сериализовать объект в текст json, а затем десериализовать текст, чтобы получить новый объект.

gson, который на основе отражения будет работать в большинстве случаев, за исключением того, что поля transient не будут скопированы и объекты с круговой ссылкой с причиной StackOverflowError.

public static <T> T copy(T anObject, Class<T> classInfo) {
    Gson gson = new GsonBuilder().create();
    String text = gson.toJson(anObject);
    T newObject = gson.fromJson(text, classInfo);
    return newObject;
}
public static void main(String[] args) {
    String originalObject = "hello";
    String copiedObject = copy(originalObject, String.class);
}
6 голосов
/ 15 сентября 2011
import com.thoughtworks.xstream.XStream;

public class deepCopy {
    private static  XStream xstream = new XStream();

    //serialize with Xstream them deserialize ...
    public static Object deepCopy(Object obj){
        return xstream.fromXML(xstream.toXML(obj));
    }
}
4 голосов
/ 17 октября 2014

Я использовал Dozer для клонирования Java-объектов, и это здорово, библиотека Kryo - еще одна отличная альтернатива.

2 голосов
/ 11 ноября 2016

1)

public static Object deepClone(Object object) {
   try {
     ByteArrayOutputStream baos = new ByteArrayOutputStream();
     ObjectOutputStream oos = new ObjectOutputStream(baos);
     oos.writeObject(object);
     ByteArrayInputStream bais = new ByteArrayInputStream(baos.toByteArray());
     ObjectInputStream ois = new ObjectInputStream(bais);
     return ois.readObject();
   }
   catch (Exception e) {
     e.printStackTrace();
     return null;
   }
 }

2)

    // (1) create a MyPerson object named Al
    MyAddress address = new MyAddress("Vishrantwadi ", "Pune", "India");
    MyPerson al = new MyPerson("Al", "Arun", address);

    // (2) make a deep clone of Al
    MyPerson neighbor = (MyPerson)deepClone(al);

Здесь классы MyPerson и MyAddress должны реализовывать интерфейс serilazable

1 голос
/ 16 февраля 2016

BeanUtils отлично справляется с глубоким клонированием бобов.

BeanUtils.cloneBean(obj);
...