如何按值复制对象,而不是按引用复制

时间:2010-04-12 17:53:53

标签: java

我想制作一个对象的副本,然后在一些逻辑之后,重新为原始对象分配副本的值。

示例:

User userCopy = //make a copy

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

  UserDao.Update(user)


  user = userCopy; 

}

我不想通过引用复制它,它必须是按值复制。

上面只是一个示例,而不是我真正想要如何使用它,但我需要学习如何按值复制。

7 个答案:

答案 0 :(得分:30)

以下是我听过的一些技巧:

  1. 如果类实现clone(),请使用Cloneable。这个API在java中有点缺陷,我从未完全理解为什么clone未在接口中定义,而是在Object中。不过,它可能会奏效。

  2. 手动创建克隆。如果存在接受所有参数的构造函数,则可能很简单,例如new User( user.ID, user.Age, ... )。您甚至可能需要一个带有用户的构造函数:new User( anotherUser ).

  3. 实现从/向用户复制的内容。该类可以使用方法copy( User ),而不是使用构造函数。然后,您可以先对对象backupUser.copy( user )进行快照,然后将其还原user.copy( backupUser )。您可能拥有名为backup / restore / snapshot的方法的变体。

  4. 使用state pattern

  5. 使用serialization。如果您的对象是图形,则可能更容易序列化/反序列化它以获得克隆。

  6. 这一切都取决于用例。选择最简单的。

    修改

    我还建议您查看以下问题:

答案 1 :(得分:7)

如果您的对象具有不可变对象和/或基元,您可以使用clone(),但如果您没有这些(例如集合)可能需要它们,则可能会有一点问题执行深度克隆。

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

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

    UserDao.update(user)
    user = userCopy; 
}

您似乎只想保留属性为age的{​​{1}}和id属性,所以,为什么不尝试一下,看看它是否有效。

对于更复杂的场景,您可以创建“复制”方法:

int

大概需要10分钟。

然后你可以改用它:

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

要阅读有关克隆的更多信息,请阅读Joshua Bloch "Effective Java: Override clone judiciously"

中的这一章

答案 2 :(得分:3)

我相信.clone()正是您所寻找的,只要课程支持它。

答案 3 :(得分:2)

你不能只做一个复制构造函数吗?顺便说一句,Java总是按值传递引用,所以你一直指向同一个对象。

答案 4 :(得分:1)

您需要从用户复制到用户复制,然后在登录后,您可以将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;       
}

答案 5 :(得分:0)

这是什么语言?如果您使用的语言通过Java等引用传递所有内容(本机类型除外),通常可以调用.clone()方法。 .clone()方法通常通过将所有相关实例字段复制/克隆到新对象中来实现。

答案 6 :(得分:0)

我知道这有点太晚了,但它可能只对某人有帮助。

在我的情况下,我已经有了一个从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 
}