Java对象复制的最佳选择?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/3144673/
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
Java object copy best option?
提问by aeq
Possible Duplicate:
How do I copy an object in Java?
可能的重复:
如何在 Java 中复制对象?
I need to copy an object in Java (i.e. copy the object "by value not by reference" so that the new object is not just a reference to the old). I'm weary of implementing clonable and would prefer to use a copy constructor. However, the class I need to copy has MANY member variables that need to be copied (over 100) so adding a new constructor to the class just for copying (which is only needed in a 1 part of my application) seems like a poor solution due to its enourmous length.
我需要在 Java 中复制一个对象(即“按值而不是按引用”复制对象,以便新对象不仅仅是对旧对象的引用)。我厌倦了实现可克隆并且更喜欢使用复制构造函数。但是,我需要复制的类有许多需要复制的成员变量(超过 100 个),因此向类添加一个新的构造函数仅用于复制(仅在我的应用程序的一部分中需要)似乎是一个糟糕的解决方案由于其巨大的长度。
Is there a better solution? Should I just use clone()? Can I create a copy constructor but rather than copying all the fields over 1 by 1 can I do it reflectively? Thanks.
有更好的解决方案吗?我应该只使用 clone() 吗?我可以创建一个复制构造函数,而不是 1 乘 1 复制所有字段,我可以反射性地做吗?谢谢。
I basically just need to create a new object that is the same as the old one, but with a few (about 10 out of 100) fields changed (but I still need both objects..so the new one cannot be a reference to the old one). I am open to any suggestions.
我基本上只需要创建一个与旧对象相同的新对象,但是更改了一些(大约 100 个中的 10 个)字段(但我仍然需要两个对象......所以新对象不能作为对旧的)。我愿意接受任何建议。
采纳答案by Bozho
clone()
makes a shallow clone - it copies only the first level of fields. You should avoid using clone()
and Cloneable
, because it is very hard to implement it correctly, and it is very likely that something will be broken, although not immediately visible. See what Joshua Blochsays about this.
clone()
制作一个浅层克隆 - 它只复制第一级字段。您应该避免使用clone()
and Cloneable
,因为它很难正确实现,并且很可能会损坏某些内容,尽管不会立即可见。看看Joshua Bloch 是怎么说的。
If you want deep copy - i.e. the whole object hierarchy being cloned, I can suggest two options:
如果你想要深度复制——即克隆整个对象层次结构,我可以建议两个选项:
- if your objects implements
Serializable
, useSerializationUtils.clone(..)
(from commons-lang) - if it's not serializable, then try java deep cloning library
- 如果您的对象实现
Serializable
,请使用SerializationUtils.clone(..)
(来自commons-lang) - 如果它不可序列化,则尝试java 深度克隆库
If however, you want shallow copy - i.e. you still want all your fields copied to a new object, but the fields, and the fields' fields (etc..) point to their original values, then you can use BeanUtils.clone(..)
(from commons-beanutils)
但是,如果您想要浅拷贝 - 即您仍然希望将所有字段复制到一个新对象,但是字段和字段的字段(等)指向它们的原始值,那么您可以使用BeanUtils.clone(..)
(来自commons-beanutils)
Apart from the cloning matter - having 100 member variables isn't a good sign. Consider splitting your class into multiple classes (update: and multiple tables, using foreign keys. Of course, if that is applicable. If these are truly properties of the same object, then fine)
除了克隆问题 - 拥有 100 个成员变量并不是一个好兆头。考虑将您的类拆分为多个类(更新:和多个表,使用外键。当然,如果适用。如果这些确实是同一对象的属性,那么很好)
回答by Bevor
one option can be to use a serialization. It's not the fastest one but probably one of the safest. Look at the code on thissite:
一种选择是使用序列化。这不是最快的,但可能是最安全的之一。看看这个网站上的代码:
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.ObjectputStream;
import java.io.ObjectOutputStream;
public class DeepObjectCopy {
public static Object clone(Object copyObject) {
try {
ByteArrayOutputStream baos = new ByteArrayOutputStream(4096);
ObjectOutputStream oos = new ObjectOutputStream(baos);
oos.writeObject(copyObject);
ByteArrayInputStream bais = new ByteArrayInputStream(baos.toByteArray());
ObjectputStream ois = new ObjectputStream(bais);
Object deepCopy = ois.readObject();
return deepCopy;
} catch (IOException e) {
e.printStackTrace();
} catch(ClassNotFoundException e) {
e.printStackTrace();
}
return null;
}
}
回答by Danubian Sailor
BeanUtils
methods are based on reflection, so they are (relatively) slow. So is dozerand other similar tools. Copying constructor is the fastest way to do your task so if you're not coding for platform such as Androidwhen each kb of code is an issue, you should choose that way. If the only problem is writing copy constructors, you can use Eclipse plugins such as JUtils.
BeanUtils
方法基于反射,因此它们(相对)较慢。那么,推土机和其他类似的工具。复制构造函数是完成任务的最快方式,因此如果您不是为Android等平台编码,而每 kb 代码都是一个问题,则应该选择这种方式。如果唯一的问题是编写复制构造函数,则可以使用 Eclipse 插件,例如JUtils。