Вопрос-ответ

How do you make a deep copy of an object?

Как создать глубокую копию объекта?

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

Переведено автоматически
Ответ 1

Безопасный способ - сериализовать объект, а затем десериализовать. Это гарантирует, что все будет совершенно новой ссылкой.

Вот статья о том, как сделать это эффективно.

Предостережения: Классы могут переопределять сериализацию таким образом, что новые экземпляры не создаются, например, для одиночек. Также это, конечно, не сработает, если ваши классы не сериализуемы.

Ответ 2

Несколько человек упоминали об использовании или переопределении Object.clone(). Не делайте этого. Object.clone() имеет несколько серьезных проблем, и в большинстве случаев его использование не рекомендуется. Пожалуйста, ознакомьтесь с пунктом 11 из "Эффективной Java" Джошуа Блоха для получения полного ответа. Я считаю, что вы можете безопасно использовать Object.clone() для массивов примитивного типа, но помимо этого вам нужно быть разумным в отношении правильного использования и переопределения clone.

Схемы, основанные на сериализации (XML или иной), сложны.

Здесь нет простого ответа. Если вы хотите выполнить глубокое копирование объекта, вам придется пройти по графу объектов и явно скопировать каждый дочерний объект с помощью конструктора копирования объекта или статического фабричного метода, который, в свою очередь, глубоко копирует дочерний объект. Неизменяемые объекты (например, Strings) копировать не нужно. Кроме того, по этой причине вы должны отдавать предпочтение неизменяемости.

Ответ 3

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

Ваш объект, который вы хотите скопировать, должен будет сделать это implement serializable. Если класс не является окончательным или не может быть изменен, расширьте класс и реализуйте serializable .

Преобразуйте свой класс в поток байтов:

ByteArrayOutputStream bos = new ByteArrayOutputStream();
ObjectOutputStream oos = new ObjectOutputStream(bos);
oos.writeObject(object);
oos.flush();
oos.close();
bos.close();
byte[] byteData = bos.toByteArray();

Восстановите свой класс из потока байтов:

ByteArrayInputStream bais = new ByteArrayInputStream(byteData);
Object object = new ObjectInputStream(bais).readObject();
Ответ 4

Вы можете выполнить глубокое клонирование на основе сериализации, используя org.apache.commons.lang3.SerializationUtils.clone(T) в Apache Commons Lang, но будьте осторожны — производительность ужасна.

В общем, рекомендуется писать свои собственные методы клонирования для каждого класса объекта в графе объектов, нуждающегося в клонировании.

java class