如何复制Java中的对象?
考虑下面的代码:
DummyBean dum = new DummyBean();
dum.setDummy("foo");
System.out.println(dum.getDummy()); // prints 'foo'
DummyBean dumtwo = dum;
System.out.println(dumtwo.getDummy()); // prints 'foo'
dum.setDummy("bar");
System.out.println(dumtwo.getDummy()); // prints 'bar' but it should print 'foo'
所以,我想将dum
复制到dumtwo
并在不影响dumtwo
情况下更改dum
。 但上面的代码没有这样做。 当我改变dum
某些东西时, dumtwo
也会发生同样的变化。
我想,当我说dumtwo = dum
,Java 只复制参考 。 那么,有什么办法可以创建dum
的新副本并将其分配给dumtwo
?
创建一个拷贝构造函数:
class DummyBean {
private String dummy;
public DummyBean(DummyBean another) {
this.dummy = another.dummy; // you can access
}
}
每个对象都有一个克隆方法可用于复制对象,但不要使用它。 创建一个类并做不适当的克隆方法太容易了。 如果你打算这么做的话,至少应该阅读Joshua Bloch在Effective Java中对此的评论。
基本: Java中的对象复制。
让我们假设一个object- obj1
,它包含两个对象, 包含 obj1
和containedObj2 。
浅拷贝:
浅复制创建一个新的instance
同一类,并将所有字段添加到新的实例,并返回它。 对象类提供了一种clone
方法,并为浅拷贝提供支持。
深拷贝:
当对象与其引用的对象一起复制时,会发生深层复制。 在图像下方显示obj1
,其中已执行深层复制。 不仅obj1
被复制,而且其中包含的对象也被复制。 我们可以使用Java Object Serialization
来进行深层复制。 不幸的是,这种方法也有一些问题(详细的例子)。
可能的问题:
clone
很难正确实施。
最好使用防御性复制,复制构造函数(如@egaga回复)或静态工厂方法。
clone()
方法,但是在编译时你不知道对象的类型,那么你有问题。 Java有一个叫做Cloneable
的接口。 在实践中,我们应该实现这个接口,如果我们想创建一个对象Cloneable
。 Object.clone
是受保护的 ,所以我们必须用一个公共方法覆盖它,以便它可以被访问。 clone()
方法也进行深度复制,这太冒险了。 你必须控制所有类中的代码。 例如,org.apache.commons.lang.SerializationUtils将具有使用序列化(Source)进行深度克隆的方法。 如果我们需要克隆Bean,那么在org.apache.commons.beanutils(Source)中有几个实用方法。
cloneBean
会根据可用的属性getters和setter克隆一个bean,即使这个bean类本身没有实现Cloneable。 copyProperties
会将属性值从源bean复制到目标Bean。 请按照以下方式操作:
public class Deletable implements Cloneable{
private String str;
public Deletable(){
}
public void setStr(String str){
this.str = str;
}
public void display(){
System.out.println("The String is "+str);
}
protected Object clone() throws CloneNotSupportedException {
return super.clone();
}
}
无论你想获得另一个对象,简单地执行克隆。 例如:
Deletable del = new Deletable();
Deletable delTemp = (Deletable ) del.clone(); // this line will return you an independent
// object, the changes made to this object will
// not be reflected to other object
链接地址: http://www.djcxy.com/p/40753.html