Object类中既然已经有了一个定义实例拷贝操作的方法clone(),那为什么还是需要让想具备实力拷贝功能的类实现Cloneable接口呢?其实,Cloneable接口在这里起到了一种标识的作用,表明实现它的类具备了实例拷贝功能。因此如果其他类没有实现这个接口,调用clone()方法时会抛异常CloneNotSupportedException
public interface Cloneable {
}
clone()方法会把对象中的字段拷贝给另一个对象。字段拷贝的过程中有浅拷贝和深拷贝。clone()方法默认是浅拷贝。
浅拷贝:字段是基本数据类型(如int、double等),则会复制字段的值到一个新的变量中,而字段是引用类型,则仅会将引用值复制给新对象中的相应字段中,也就是说,两个字段指向了同一个对象实例。
**深拷贝:**对于引用型变量,深拷贝会开辟一块新的内存空间,将被复制引用所指向的对象实例的各个属性复制到新的内存空间中,然后将新的引用指向块内存。
演示demo
public class CloneableDemo implements Cloneable {
int basicValue;
Integer refValue;
public CloneableDemo(int basicValue, Integer refValue) {
this.basicValue = basicValue;
this.refValue = refValue;
}
// @Override
// public CloneableDemo clone() {
// try {
// CloneableDemo clone = (CloneableDemo) super.clone();
// clone.setRefValue(new Integer(clone.getRefValue()));
// // TODO: copy mutable state here, so the clone can't change the internals of the original
// return clone;
// } catch (CloneNotSupportedException e) {
// throw new AssertionError();
// }
// }
public static void main(String[] args) throws Exception {
CloneableDemo cloneableDemo = new CloneableDemo(1000, 10000);
CloneableDemo newCloneableDemo = (CloneableDemo)cloneableDemo.clone();
// 使用默认clone,输出true。重写clone(),输出false,
System.out.println(cloneableDemo.getRefValue() == newCloneableDemo.getRefValue());
}
}