Рассмотрим код ниже:
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
?
Базовый: Копирование объектов в Java.
Давайте предположим
obj1
, что объект - содержит два объекта, содержащихся в Obsj1 и в составе В2 .поверхностное копирование:
поверхностное копирование создает новый объект
instance
того же класса, копирует все поля в новый экземпляр и возвращает его. Класс объекта предоставляетclone
метод и обеспечивает поддержку мелкого копирования.Глубокое копирование.
Глубокое копирование происходит, когда объект копируется вместе с объектами, на которые он ссылается . Ниже показано изображение
obj1
после того, как на нем было выполнено глубокое копирование. Мало того, чтоobj1
было скопировано , но также и объекты, содержащиеся в нем. Мы можем использовать,Java Object Serialization
чтобы сделать глубокую копию. К сожалению, у этого подхода есть некоторые проблемы ( подробные примеры ).Возможные проблемы:
clone
сложно реализовать правильно.Лучше использовать Защитное копирование , конструкторы копирования (как ответ @egaga) или статические фабричные методы .
clone()
метод, но вы не знаете тип объекта во время компиляции, тогда у вас есть проблема. У Java есть интерфейс под названиемCloneable
. На практике мы должны реализовать этот интерфейс, если мы хотим создать объектCloneable
.Object.clone
будет защищена , поэтому мы должны переопределить его с помощью открытого метода для того , чтобы быть доступным.clone()
метод всех переменных объекта-члена также выполняет глубокое копирование, это слишком рискованно для предположения. Вы должны контролировать код во всех классах.Например, org.apache.commons.lang.SerializationUtils будет иметь метод для глубокого клонирования с использованием сериализации ( Source ). Если нам нужно клонировать Bean, то в org.apache.commons.beanutils ( Source ) есть несколько служебных методов .
cloneBean
Будет клонировать компонент на основе доступных методов получения и установки свойств, даже если сам класс компонента не реализует Cloneable.copyProperties
Скопирует значения свойств из исходного объекта в целевой для всех случаев, когда имена свойств совпадают.источник
В упаковке
import org.apache.commons.lang.SerializationUtils;
есть метод:Пример:
источник
Serializable
Просто следуйте инструкциям ниже:
и где бы вы ни хотели получить другой объект, просто выполните клонирование. например:
источник
Почему нет ответа на использование Reflection API?
Это действительно просто.
РЕДАКТИРОВАТЬ: включить дочерний объект с помощью рекурсии
источник
Class A { B child; } Class B{ A parent; }
class car { car car = new car(); }
Я использую библиотеку Google JSON для ее сериализации, а затем создаю новый экземпляр сериализованного объекта. Это делает глубокое копирование с несколькими ограничениями:
не может быть никаких рекурсивных ссылок
он не будет копировать массивы разнородных типов
массивы и списки должны быть напечатаны, иначе не будет найден класс для создания экземпляра
вам может понадобиться инкапсулировать строки в объявленном вами классе
Я также использую этот класс для сохранения пользовательских настроек, окон и прочего для перезагрузки во время выполнения. Это очень удобно и эффективно.
источник
Да, вы просто делаете ссылку на объект. Вы можете клонировать объект, если он реализует
Cloneable
.Проверьте эту статью вики о копировании объектов.
См. Здесь: копирование объектов
источник
Добавьте
Cloneable
и ниже код для вашего классаИспользовать этот
clonedObject = (YourClass) yourClassObject.clone();
источник
Да. Вам нужно Deep Copy вашего объекта.
источник
Это тоже работает. Предполагаемая модель
Сначала добавьте
compile 'com.google.code.gson:gson:2.8.1'
в свое приложение> gradle & sync. затемВы можете исключить использование поля с помощью
transient
ключевого слова после модификатора доступа.Примечание: это плохая практика. Также не рекомендуется использовать
Cloneable
илиJavaSerialization
это медленно и сломано. Написать конструктор копирования для лучшей производительности ref .Что-то вроде
Тестовая статистика 90000 итераций:
линия
UserAccount clone = gson.fromJson(gson.toJson(aO), UserAccount.class);
занимает 808 мсЛиния
UserAccount clone = new UserAccount(aO);
занимает менее 1 мсВывод: используйте gson, если ваш босс сумасшедший и вы предпочитаете скорость. Используйте второй конструктор копирования, если вы предпочитаете качество.
Вы также можете использовать плагин генератора кода конструктора копирования в Android Studio.
источник
Вот достойное объяснение,
clone()
если вам это понадобится ...Здесь: клон (метод Java)
источник
Используйте утилиту глубокого клонирования:
Это позволит глубоко скопировать любой объект Java, проверьте его на https://github.com/kostaskougios/cloning
источник
Глубокое клонирование - это ваш ответ, который требует реализации
Cloneable
интерфейса и переопределенияclone()
метода.Вы будете называть это так
DummyBean dumtwo = dum.clone();
источник
dummy
, AString
, неизменен, вам не нужно копировать егоДля этого вам нужно каким-то образом клонировать объект. Хотя в Java есть механизм клонирования, не используйте его, если это не нужно. Создайте метод копирования, который работает для вас, а затем выполните:
Вот еще несколько советов по различным методам выполнения копирования.
источник
Помимо явного копирования, другой подход заключается в том, чтобы сделать объект неизменным (нет
set
или другие методы-мутаторы). Таким образом, вопрос никогда не возникает. Неизменяемость становится более сложной для более крупных объектов, но другой стороной этого является то, что она толкает вас в направлении разделения на согласованные мелкие объекты и композиты.источник
Альтернатива конструктору метода egaga копирования. Возможно, у вас уже есть POJO, поэтому просто добавьте еще один метод,
copy()
который возвращает копию инициализированного объекта.Если у вас уже есть
DummyBean
и вам нужна копия:Но оба хорошо работают, это в конечном итоге зависит от вас ...
источник
источник
Вы можете глубоко копировать автоматически с помощью XStream, с http://x-stream.github.io/ :
Добавьте его в свой проект (если используете maven)
затем
При этом у вас есть копия без необходимости реализации какого-либо интерфейса клонирования.
источник
java.beans.XMLEncoder
стандартный Java API, который также сериализуется в XML (хотя и не для целей глубокого копирования).и в вашем коде:
источник
Передайте объект, который вы хотите скопировать, и получите нужный объект:
Теперь разбираем
objDest
нужный объект.Удачного кодирования!
источник
Вы можете попытаться реализовать
Cloneable
и использоватьclone()
метод; Однако, если вы используете метод клонирования Вам необходимы - по стандартному - всегда отменяетObject
«spublic Object clone()
метода.источник
Если вы можете добавить аннотацию к исходному файлу, можно использовать процессор аннотаций или генератор кода, подобный этому .
DummyBeanBuilders
Будет сгенерирован класс , который имеет статический методdummyBeanUpdater
для создания мелких копий, так же, как вы делаете это вручную.источник
Используйте
gson
для дублирования объекта.Предположим , у меня есть объект
person
.soисточник