Java 如何按值复制对象,而不是按引用
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/2624165/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How to copy an object by value, not by reference
提问by Blankman
I want to make a copy of an object, then after some logic, re-assign the original object the value of the copy.
我想制作一个对象的副本,然后经过一些逻辑,重新为原始对象分配副本的值。
example:
例子:
User userCopy = //make a copy
foreach(...)
{
user.Age = 1;
user.ID = -1;
UserDao.Update(user)
user = userCopy;
}
I don't want a copy by reference, it has to be a copy by value.
我不想按引用复制,它必须是按值复制。
The above is just a sample, not how I really want to use it but I need to learn how to copy by value.
以上只是一个示例,不是我真正想如何使用它,但我需要学习如何按值复制。
回答by Petar Minchev
Can't you just make a copy constructor? By the way Java always passes references by value, so you keep pointing to the same object.
你不能只做一个复制构造函数吗?顺便说一下,Java 总是按值传递引用,所以你一直指向同一个对象。
回答by JC Ford
I believe .clone()
is what you're looking for, so long as the class supports it.
我相信.clone()
这就是你正在寻找的,只要班级支持它。
回答by KhanS
You need to do a deep copy from user to usercopy, and then after your login you can reassign your userCopy reference to user.
您需要从 user 到 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;
}
回答by Lie Ryan
what language is this? If you're using a language that passes everything by reference like Java (except for native types), typically you can call .clone()
method. The .clone() method is typically implemented by copying/cloning all relevant instance fields into the new object.
这是什么语言?如果您使用的是像 Java 这样通过引用传递所有内容的语言(本机类型除外),通常您可以调用.clone()
方法。.clone() 方法通常通过将所有相关实例字段复制/克隆到新对象中来实现。
回答by ewernli
Here are the few techniques I've heard of:
以下是我听说过的一些技巧:
Use
clone()
if the class implementsCloneable
. This API is a bit flawed in java and I never quite understood whyclone
is not defined in the interface, but inObject
. Still, it might work.Create a clone manually. If there is a constructor that accepts all parameters, it might be simple, e.g
new User( user.ID, user.Age, ... )
. You might even want a constructor that takes a User:new User( anotherUser ).
Implement something to copy from/to a user. Instead of using a constructor, the class may have a method
copy( User )
. You can then first snapshot the objectbackupUser.copy( user )
and then restore ituser.copy( backupUser )
. You might have a variant with methods namedbackup
/restore
/snapshot
.Use the state pattern.
Use serialization. If your object is a graph, it might be easier to serialize/deserialize it to get a clone.
使用
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
。使用状态模式。
使用序列化。如果您的对象是图形,则序列化/反序列化它以获得克隆可能更容易。
That all depends on the use case. Go for the simplest.
这一切都取决于用例。去最简单的。
EDIT
编辑
I also recommend to have a look at these questions:
我还建议看看这些问题:
回答by OscarRyz
You may use clone()
which works well if your object has immutable objects and/or primitives, but it may be a little problematic when you don't have these ( such as collections ) for which you may need to perform a deep clone.
clone()
如果您的对象具有不可变对象和/或原语,您可以使用 which 效果很好,但是当您没有这些(例如集合)时,您可能需要对其执行深度克隆,这可能会有点问题。
User userCopy = (User) user.clone();//make a copy
for(...) {
user.age = 1;
user.id = -1;
UserDao.update(user)
user = userCopy;
}
It seems like you just want to preserve the attributes: age
and id
which are of type int
so, why don't you give it a try and see if it works.
好像你只是想保留的属性:age
和id
它们类型的int
话,你为什么不给它一个尝试,看看它是否工作。
For more complex scenarios you could create a "copy" method:
对于更复杂的场景,您可以创建一个“复制”方法:
publc class User {
public static User copy( User other ) {
User newUser = new User();
newUser.age = other.age;
newUser.id = other.id;
//... etc.
return newUser;
}
}
It should take you about 10 minutes.
大约需要 10 分钟。
And then you can use that instead:
然后你可以改用它:
User userCopy = User.copy( user ); //make a copy
// etc.
To read more about clone read this chapter in Joshua Bloch "Effective Java: Override clone judiciously"
要阅读有关克隆的更多信息,请阅读 Joshua Bloch “Effective Java: Override clone judiciously”中的这一章
回答by user2612526
I know this is a little bit too late but it might just help someone.
我知道这有点太晚了,但它可能只是帮助某人。
In my case I already had a method to make the Object from a json Object and make json from the object. with this you can simply create a new instance of the object and use it to restore. For instance in a function parsing a final object
就我而言,我已经有了一种方法可以从 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
}