在Java中要实现克隆很简单,只要在需要克隆的类实现Cloneable,并调用其clone方法即可。最简单的克隆如下
package cn.quinn.test;
public class TEST implements Cloneable {
public String id;
public T2 t2;
public static void main(String[] args) {
TEST t = new TEST();
t.id = "1";
try {
TEST t2 = (TEST) t.clone();
System.out.println(t);
System.out.println(t2);
System.out.println(t2.id);
} catch (CloneNotSupportedException e) {
e.printStackTrace();
}
}
}
打印结果为
cn.quinn.test.TEST@1fb8ee3
cn.quinn.test.TEST@61de33
1
可以看到t和t2已经不是一个对象,但是id值相同。
Java中的克隆分为浅克隆和深克隆
默认的克隆方法提供的为浅克隆,浅克隆表现方式如下
package cn.quinn.test;
public class TEST implements Cloneable {
public String id;
public T2 t2;
public static void main(String[] args) {
TEST t = new TEST();
T2 t21 = new T2(); //new一个属性对象
t.t2 = t21;//把T2的对象传给t
System.out.println(t21); //打印一下
try {
TEST t2 = (TEST) t.clone();
System.out.println(t2.t2); //克隆结果
} catch (CloneNotSupportedException e) {
e.printStackTrace();
}
}
}
打印结果
cn.quinn.test.T2@61de33
cn.quinn.test.T2@61de33
两个对象完全相同,这就是浅copy,当更改克隆后的对象属性的值后会影响到克隆前的对象,因为它们是同一块内存地址。
在Java中如何实现深度克隆呢?
方法很多 可以重写属性类的clone方法 ,这样做不好的地方就是一旦对象属性过多就会写很多
最好的方法就是序列化和反序列化,不过所有的类和属性类都必须实现Serializable接口
如下
package cn.quinn.test;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.Serializable;
public class TEST implements Cloneable, Serializable {
public String id;
public T2 t2;
@Override
protected Object clone() throws CloneNotSupportedException {
ByteArrayOutputStream byteout = null;
ObjectOutputStream out = null;
ByteArrayInputStream bytein = null;
ObjectInputStream in = null;
try {
byteout = new ByteArrayOutputStream();
out = new ObjectOutputStream(byteout);
out.writeObject(this);
bytein = new ByteArrayInputStream(byteout.toByteArray());
in = new ObjectInputStream(bytein);
return in.readObject();
} catch (Exception e) {
e.printStackTrace();
} finally {
try {
if (in != null) {
in.close();
in = null;
}
} catch (Exception e) {
}
try {
if (bytein != null) {
bytein.close();
bytein = null;
}
} catch (Exception e) {
}
try {
if (out != null) {
out.close();
out = null;
}
} catch (Exception e) {
}
try {
if (byteout != null) {
byteout.close();
byteout = null;
}
} catch (Exception e) {
}
}
return null;
}
public static void main(String[] args) {
TEST t = new TEST();
T2 t21 = new T2(); //new一个属性对象
t.t2 = t21;//把T2的对象传给t
System.out.println(t21); //打印一下
try {
TEST t2 = (TEST) t.clone();
System.out.println(t2.t2); //克隆结果
} catch (CloneNotSupportedException e) {
e.printStackTrace();
} catch (Exception e) {
e.printStackTrace();
}
}
}
package cn.quinn.test;
import java.io.Serializable;
public class T2 implements Serializable{
private String t2;
public String getT2() {
return t2;
}
public void setT2(String t2) {
this.t2 = t2;
}
}