如何按值而不是按引用复制对象[重复]
Posted
技术标签:
【中文标题】如何按值而不是按引用复制对象[重复]【英文标题】:How to copy an object by value, not by reference [duplicate] 【发布时间】:2011-02-07 03:00:49 【问题描述】:我想制作一个对象的副本,然后经过一些逻辑,重新为原始对象分配副本的值。
示例:
User userCopy = //make a copy
foreach(...)
user.Age = 1;
user.ID = -1;
UserDao.Update(user)
user = userCopy;
我不想要按引用复制,它必须是按值复制。
以上只是一个示例,并不是我真正想使用的方式,但我需要学习如何按值复制。
【问题讨论】:
【参考方案1】:你不能只做一个复制构造函数吗?顺便说一句,Java 总是按值传递引用,所以你一直指向同一个对象。
【讨论】:
其实...Java 总是按值传递。只是,对于非基元来说,值是一个参考。 Java 不通过引用传递引用。 Java 按值传递引用。【参考方案2】:我相信.clone()
是您正在寻找的东西,只要该类支持它。
【讨论】:
咳咳。我们都知道克隆是邪恶的:) 这不是邪恶的,只是被误解了。这意味着好。【参考方案3】:您需要从用户到用户副本进行深度复制,然后在登录后您可以将您的 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;
【讨论】:
【参考方案4】:这是什么语言?如果您使用的语言通过引用传递所有内容,例如 Java(本机类型除外),通常可以调用 .clone()
方法。 .clone() 方法通常通过将所有相关实例字段复制/克隆到新对象中来实现。
【讨论】:
【参考方案5】:以下是我听说过的几种技术:
如果类实现了Cloneable
,则使用clone()
。这个API在java中有点缺陷,我一直不太明白为什么clone
没有在接口中定义,而是在Object
中。不过,它可能会起作用。
手动创建克隆。如果有一个接受所有参数的构造函数,它可能很简单,例如new User( user.ID, user.Age, ... )
。你甚至可能想要一个带有用户的构造函数:new User( anotherUser ).
实现从/向用户复制的内容。该类可能有一个方法copy( User )
,而不是使用构造函数。然后,您可以先对对象backupUser.copy( user )
进行快照,然后再将其还原为user.copy( backupUser )
。您可能有一个带有名为 backup
/restore
/snapshot
的方法的变体。
使用state pattern。
使用serialization。如果你的对象是一个图,序列化/反序列化它可能更容易获得一个克隆。
这一切都取决于用例。选择最简单的。
编辑
我还建议看看这些问题:
Clone() vs. Copy constructor How to properly override clone method【讨论】:
【参考方案6】:如果您的对象具有不可变对象和/或原语,您可以使用clone()
,它会很好地工作,但是当您没有可能需要执行的这些(例如集合)时,它可能会有点问题深度克隆。
User userCopy = (User) user.clone();//make a copy
for(...)
user.age = 1;
user.id = -1;
UserDao.update(user)
user = userCopy;
您似乎只想保留属性:age
和 id
,它们的类型为 int
,所以,您为什么不尝试一下,看看它是否有效。
对于更复杂的场景,您可以创建“复制”方法:
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 "Effective Java: Override clone judiciously" 中的本章
【讨论】:
【参考方案7】:我知道这有点太晚了,但它可能会对某人有所帮助。
在我的例子中,我已经有一种方法可以从 json 对象生成对象并从对象生成 json。有了这个,您可以简单地创建对象的新实例并使用它来恢复。例如在解析最终对象的函数中
public void update(final Object object)
final Object original = Object.makeFromJSON(object.toJSON());
// the original is not affected by changes made to object
【讨论】:
这行得通..谢谢以上是关于如何按值而不是按引用复制对象[重复]的主要内容,如果未能解决你的问题,请参考以下文章
在 Python 2 中,无论列表的内容如何,如何按值而不是引用复制复杂嵌套元素的列表