ClassA a = new ClassA();
ClassA b = a;
上述两条语句,b对象直接引用了a对象,如果ClassA里面有其他属性,则a和b由于是同一个对象,所以属性的值也是一样的。假如现在我们需要一个和a一样的对象,即复制,这时候比较无脑的做法是new一个ClassA,然后把a对象里面的属性全部无脑拷贝到新建的对象c里面。
但是上述的方法真的有效吗?
不是的。如果a对象里面的属性全是基础类型int,byte,string等,那到时能实现这样的复制目的。但是如果a对象里面的属性也是对象,那么修改c对象的属性,则a对象的对应属性也是会被修改的。
ClassA a = new ClassA();
ClassA c = new ClassA();
c.cla=a.cla;
//此时修改a.cla,那么c.cla也会被修改
class ClassA{
public ClassB cla;
}
java克隆方法:深度克隆与浅层克隆
浅层克隆,不需要向上述方法那样重新new一个新对象,再把对象的属性无脑照搬。
实现方法:
1、克隆对象的类实现cloneable接口
2、重写clone方法
public class A implements Cloneable{
public B b ;
//重写clone方法
public Object clone(){
Object o = null;
try {
o= super.clone();
} catch (CloneNotSupportedException e) {
e.printStackTrace();
}
return o;
}
}
clone方法是object类的native方法,该native方法具体是做什么并没细查,只知道该native方法实现的功能与刚才上面的实现无脑克隆方法是一样的,new一个新对象,并把属性复制过去。该方法也是没能解决问题,但是代码量也就少了很多。接下来介绍深度克隆方法。
深度克隆有两种实现方式,一种是用流的形式,另外一种是根据浅克隆,对其属性也进行克隆来达到深度克隆的效果。
1、流的形式:要复制的类要实现序列化,包括类的属性。
public class A implements Serializable{
public B b ;
public A getCopy(){
ByteArrayOutputStream bos = new ByteArrayOutputStream();
ObjectOutputStream oos = new ObjectOutputStream(bos);
oos.writeObject(this);
ByteArrayInputStream bis = new ByteArrayInputStream(bos.toByteArray());
ObjectInputStream ois = new ObjectInputStream(bis);
A o =(A) ois.readObject();
return o;
}
}
A a = new A();
A c = a.getCopy();
//此时a对象与c对象是不同对象,包含的属性虽然值相同,但是也是不同对象。
2、clone方式
public Class B implements Cloneable{
public Object clone(){
//try catch
return super.clone();
}
}
//同时在A的clone方法添加上属性的clone
/**
*A类里
*/
public Object clone(){
A o =null;
o=(A)super.clone;
o.b=b.clone();
}
//有多少属性不是基础类型的都要这样子搞,也能达到深度克隆的效果
对比深度克隆的两种实现方法的效果,两种方法都不是很方便,流的方法每个属性都要实现序列化。而clone方法不止需要实现cloneable接口,还得再clone方法里即对本身克隆,又要对属性进行克隆,十分不便。而时效性方面,clone方法要比实现流的方法快速的多,所以总结,一般不要进行深度克隆。