产生深克隆与浅克隆的原因是调用clone()方法,对于引用类型变量,克隆出来的对象,克隆的是引用地址,所以在克隆出来对象里面对这些引用类型变量,进行修改,会影响先前的对象数据。
下面直接贴出代码,需要注意两点:clone方法的实现,需要注意,因为Object的clone方法是Project的类型,所以要想在外面调用clone方法,必须重写;第二点:就是深拷贝,就是对象实现序列化接口,然后通过字节流方式进行深拷贝。
浅拷贝代码:
public class ShadowClone implements Cloneable{
// 基本类型
private int a;
// 非基本类型
private String b;
// 非基本类型
private int[] c;
public ShadowClone(){
this(0,"",new int[0]);
}
public ShadowClone(int a,String b,int[] c){
this.a = a;
this.b = b;
this.c = c;
}
// 重写Object.clone()方法,并把protected改为public
@Override
public Object clone()
{
ShadowClone sc = null;
try
{
sc = (ShadowClone) super.clone();
} catch (CloneNotSupportedException e)
{
e.printStackTrace();
}
return sc;
}
public int getA()
{
return a;
}
public void setA(int a)
{
this.a = a;
}
public String getB()
{
return b;
}
public void setB(String b)
{
this.b = b;
}
public int[] getC()
{
return c;
}
public void setC(int[] c)
{
this.c = c;
}
public class Test {
/**
* @param args
*/
public static void main(String[] args) {
ShadowClone shadowClone = new ShadowClone(12,"zhangsan",new int[]{1,2,3});
shadowClone.setA(12);
shadowClone.setB("zhangsan");
shadowClone.setC(new int[]{1,2,3});
System.out.println("克隆前: c1.a="+shadowClone.getA() );
System.out.println("克隆前: c1.b="+shadowClone.getB() );
System.out.println("克隆前: c1.c[0]="+shadowClone.getC()[0]);
System.out.println("---------------") ;
ShadowClone shadowClone2 = (ShadowClone)shadowClone.clone();
shadowClone2.setA(13);
shadowClone2.setB("lisi");
int[] c = shadowClone2.getC();
c[0] = 4;
shadowClone2.setC(c);
System.out.println("克隆后: c1.a="+shadowClone.getA() );
System.out.println("克隆后: c1.b="+shadowClone.getB() );
System.out.println("克隆后: c1.c[0]="+shadowClone.getC()[0]);
System.out.println("---------------") ;
System.out.println("克隆后: c2.a=" + shadowClone2.getA());
System.out.println("克隆后: c2.b=" + shadowClone2.getB());
System.out.println("克隆后: c2.c[0]=" + shadowClone2.getC()[0]);
}
深拷贝代码:
import java.io.Serializable;
public class DeepClone implements Serializable{
private int a;
private String b;
private int[] c;
public int getA()
{
return a;
}
public void setA(int a)
{
this.a = a;
}
public String getB()
{
return b;
}
public void setB(String b)
{
this.b = b;
}
public int[] getC()
{
return c;
}
public void setC(int[] c)
{
this.c = c;
}
}
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
public class TestDeep {
public static void main(String[] args) {
TestDeep test = new TestDeep();
DeepClone shadowClone = new DeepClone();
shadowClone.setA(12);
shadowClone.setB("zhangsan");
shadowClone.setC(new int[]{1,2,3});
System.out.println("克隆前: c1.a="+shadowClone.getA() );
System.out.println("克隆前: c1.b="+shadowClone.getB() );
System.out.println("克隆前: c1.c[0]="+shadowClone.getC()[0]);
System.out.println("---------------") ;
//调用深拷贝方法
DeepClone shadowClone2 = (DeepClone)test.deepClone(shadowClone);
shadowClone2.setA(13);
shadowClone2.setB("lisi");
int[] c = shadowClone2.getC();
c[0] = 4;
shadowClone2.setC(c);
System.out.println("克隆后: c1.a="+shadowClone.getA() );
System.out.println("克隆后: c1.b="+shadowClone.getB() );
System.out.println("克隆后: c1.c[0]="+shadowClone.getC()[0]);
System.out.println("---------------") ;
System.out.println("克隆后: c2.a=" + shadowClone2.getA());
System.out.println("克隆后: c2.b=" + shadowClone2.getB());
System.out.println("克隆后: c2.c[0]=" + shadowClone2.getC()[0]);
}
// 用序列化与反序列化实现深克隆
public Object deepClone(Object src) {
Object o = null;
if(src != null){
try {
//采用 输出流对象转换成到字节流
ByteArrayOutputStream baos = new ByteArrayOutputStream();
ObjectOutputStream oos = new ObjectOutputStream(baos);
oos.writeObject(src);
oos.close();
//运行对象的字节流反序列化生成对象
ByteArrayInputStream bais = new ByteArrayInputStream(baos
.toByteArray());
ObjectInputStream ois = new ObjectInputStream(bais);
o = ois.readObject();
ois.close();
} catch (IOException e) {
e.printStackTrace();
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
}
return o;
}
}