Подтвердить что ты не робот

Как скопировать объект по значению, а не по ссылке

Я хочу сделать копию объекта, а затем после некоторой логики повторно назначить исходному объекту значение копии.

Пример:

User userCopy = //make a copy

foreach(...)
{
  user.Age = 1;
  user.ID = -1;

  UserDao.Update(user)


  user = userCopy; 

}

Мне не нужна копия по ссылке, она должна быть копией по значению.

Выше приведен пример, а не то, как я действительно хочу его использовать, но мне нужно научиться копировать по значению.

4b9b3361

Ответ 1

Вот несколько методов, о которых я слышал:

  • Используйте clone(), если класс реализует Cloneable. Этот API немного испорчен в java, и я никогда не понимал, почему clone не определено в интерфейсе, а в Object. Тем не менее, это может сработать.

  • Создайте клон вручную. Если есть конструктор, который принимает все параметры, он может быть простым, например new User( user.ID, user.Age, ... ). Вам может даже понадобиться конструктор, который принимает пользователя: new User( anotherUser ).

  • Внедрить что-то для копирования с/на пользователя. Вместо использования конструктора класс может иметь метод copy( User ). Затем вы можете сначала сделать снимок объекта backupUser.copy( user ), а затем восстановить его user.copy( backupUser ). У вас может быть вариант с методами с именем backup/restore/snapshot.

  • Используйте шаблон состояния .

  • Используйте сериализация. Если ваш объект является графиком, может быть проще сериализовать/десериализовать его, чтобы получить клон.

Все зависит от варианта использования. Идите для простейшего.

ИЗМЕНИТЬ

Я также рекомендую посмотреть на эти вопросы:

Ответ 2

Вы можете использовать clone(), который хорошо работает, если у объекта есть неизменяемые объекты и/или примитивы, но это может быть немного проблематично, если у вас их нет (например, коллекции), для которых вам может потребоваться выполнить глубокий клон.

User userCopy = (User) user.clone();//make a copy

for(...) {
    user.age = 1;
    user.id = -1;

    UserDao.update(user)
    user = userCopy; 
}

Похоже, вы просто хотите сохранить атрибуты: age и id, которые имеют тип int, поэтому почему бы вам не попробовать и посмотреть, работает ли он.

Для более сложных сценариев вы можете создать метод "copy":

publc class User { 
    public static User copy( User other ) {
         User newUser = new User();
         newUser.age = other.age;
         newUser.id = other.id;
         //... etc. 
         return newUser;
    }
}

Это займет около 10 минут.

И тогда вы можете использовать это вместо:

     User userCopy = User.copy( user ); //make a copy
     // etc. 

Чтобы узнать больше о клоне, прочитайте эту главу в Joshua Bloch "Эффективная Java: переопределить клон разумно"

Ответ 3

Я считаю, что .clone() - это то, что вы ищете, если класс поддерживает его.

Ответ 4

Не можете ли вы создать конструктор копирования? Кстати, Java всегда передает ссылки по значению, поэтому вы продолжаете указывать на один и тот же объект.

Ответ 5

Вам нужно сделать глубокую копию от пользователя к usercopy, а затем после вашего входа вы можете переназначить свою ссылку userCopy пользователю.

User userCopy = new User();
userCopy.Age = user.Age
userCopy.ID = user.ID

foreach(...) 
{ 
  user.Age = 1; 
  user.ID = -1; 

  UserDao.Update(user)     

  user = userCopy;       
}

Ответ 6

какой язык это? Если вы используете язык, который передает все по ссылке, например Java (кроме родных), обычно вы можете вызвать метод .clone(). Метод .clone() обычно реализуется путем копирования/клонирования всех соответствующих полей экземпляра в новый объект.

Ответ 7

Я знаю, что это слишком поздно, но это может помочь кому-то.

В моем случае у меня уже был способ сделать Object из json Object и сделать json из объекта. с этим вы можете просто создать новый экземпляр объекта и использовать его для восстановления. Например, в функции, анализирующей конечный объект

public void update(final Object object){ 
  final Object original = Object.makeFromJSON(object.toJSON()); 
  // the original is not affected by changes made to object 
}