public class CloneTest implements Cloneable {
public long primitive;
public Long box;
public String name;
public String interest[]; // 数组
public Object object; // 这个对象无法clone,也没有意义去clone
public Other oth; // 复杂对象,也需要实现Cloneable接口
@Override
public Object clone() {
CloneTest o = null;
try {
o = (CloneTest) super.clone();
// 数组对象与 复杂对象需要进行深度复制
o.interest = interest.clone();
o.oth = (Other) oth.clone();
// Object.clone()是protected方法,无法调用
// o.object = object.clone();
} catch (CloneNotSupportedException e) {
e.printStackTrace();
}
return o;
}
public static void main(String[] args) throws Exception {
CloneTest t = new CloneTest();
t.primitive = 1;
t.box = 1L;
t.name = "leo";
t.interest = new String[] { "aa", "bb" };
t.oth = new Other();
t.oth.other = "other";
t.object = new Object();
CloneTest t2 = (CloneTest) t.clone();
t2.primitive = 2;
t2.box = 2L;
t2.name = "dongql";
t2.interest[0] = "AA";
System.out.print(t + "\t" + t.oth + "\t" + t.primitive + "\t" + t.box + "\t" + t.name + "\t" + t.interest[0]);
System.out.println("\t" + t.interest[1] + "\t" + t.object + "\t" + t.oth.other);
System.out.print(t2 + "\t" + t2.oth + "\t" + t2.primitive + "\t" + t2.box + "\t" + t2.name + "\t" + t2.interest[0]);
System.out.println("\t" + t2.interest[1] + "\t" + t2.object + "\t" + t2.oth.other);
// 修改引用
// 不进行深度复制这个也不会影响t.interest与t.object值
// 原因是t2.interest与t.object的指针被修改,而不是值被修改
// t2.interest = new String[]{"c", "d"};
t2.object = new Object();
// 修改值
t2.interest[1] = "BB";
t2.oth.other = "OTHER";
System.out.print(t2 + "\t" + t2.oth + "\t" + t2.primitive + "\t" + t2.box + "\t" + t2.name + "\t" + t2.interest[0]);
System.out.println("\t" + t2.interest[1] + "\t" + t2.object + "\t" + t2.oth.other);
}
}
class Other implements Cloneable {
public String other;
@Override
public Object clone() {
Other o = null;
try {
o = (Other) super.clone();
} catch (CloneNotSupportedException e) {
e.printStackTrace();
}
return o;
}
}
运行结果:
kk.CloneTest@1888759 kk.Other@6e1408 1 1 leo aa bb java.lang.Object@e53108 other
kk.CloneTest@f62373 kk.Other@19189e1 2 2 dongql AA bb java.lang.Object@e53108 other
kk.CloneTest@f62373 kk.Other@19189e1 2 2 dongql AA BB java.lang.Object@1f33675 OTHER
分析总结:
复制需要实现java.lang.Cloneable接口,重写clone方法
原生类型会复制值,包装类与其它类对象复制的是引用,要实现对象复制得深度复制,如:o.oth = (Other) oth.clone();
重新new一个对象并赋值给原对象这个跟clone方法实际上做的是一件事,如:t2.object = new Object();