Java中没有C++中所谓的拷贝构造函数,但是相应地提供了Cloneable接口。在Java中所有类都实现了clone()方法,因为Java中的所有类的父类Object具有clone()方法,而所有Java类都是Object类的子类。某个对象如果想要能够实现克隆,那么该对象的类必须实现cloneable接口。Cloneable接口仅仅只是一个标记接口,不包含任何需要实现的方法。如果某个对象的类没有实现Cloneable接口而调用clone()方法,那么会抛出CloneNotSupportedException。
什么叫浅克隆?什么叫深克隆?克隆就是指将值复制一份到新的对象中,而浅克隆就是对象的引用类型变量复制的是对象的引用值,深克隆就是将引用类型变量所指向的对象内存空间也复制一份给新对象。如下图所示。
如何实现对象的克隆?分三步:
- 对象的类实现Cloneable接口;
- 覆盖Object类的clone()方法;
- 在clone()方法中调用super.clone();
public class ShallowClone implements Cloneable{
public int id;
public String name;
public ShallowClone(int id, String name){
this.id = id;
this.name = name;
}
public Object clone(){
Object sc = null;
try {
sc = super.clone();
} catch (Exception e) {
System.out.println(e.toString());
}
return sc;
}
public static void main(String[] args) {
// TODO Auto-generated method stub
ShallowClone sc1 = new ShallowClone(1, "sc1Name");
ShallowClone sc2 = (ShallowClone)sc1.clone();
System.out.println("sc1's id: " + sc1.id + "\tsc2's id: " + sc2.id);
System.out.println("sc1's name: " + sc1.name + "\tsc2's name: " + sc2.name);
System.out.println(sc1.name == sc2.name);
System.out.println(sc1.name.equals(sc2.name));
}
}
输出结果:
sc1's id: 1 sc2's id: 1
sc1's name: sc1Name sc2's name: sc1Name
true
true
以上只是覆盖了Object类的clone()方法,默认的是浅克隆。String对象复制了其引用值,而不是复制了内存,否则sc1.name == sc2.name为false。
要想实现深克隆很简单,只要引用类型的成员变量所属类也实现Cloneable接口,在clone()方法里对该成员变量也调用它的clone()方法即可。