介紹
- Cloneable 接口的出現與接口的正常使用並沒有關係。這個接口只是作爲一個標記,指示類設計者瞭解克隆過程。
具體來說,它沒有指定clone 方法,這個方法是從 Object 類繼承的。
- 對象對於克隆很“ 偏執”, 如果一個對象請求克隆, 但沒有實現Cloneable接口, 就會生成一個CloneNotSupportedException異常。
- Object類的默認的克隆方法clone是“ 淺拷貝”,而非“深拷貝”,即並不會克隆對象中引用的其他對象。
- 如果需要“深拷貝”,需要類的設計者創建一個深拷貝方法,在這個方法中可以先調用超類默認的clone方法,完成淺拷貝工作,然後再手動對其他引用的對象進行拷貝。
例子
// 支持拷貝的對象(深拷貝的實現案例)
public class Employee implements Cloneable {
private String name;
private Date birthday;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Date getBirthday() {
return birthday;
}
public void setBirthday(Date birthday) {
this.birthday = birthday;
}
public Employee clone() throws CloneNotSupportedException{
Employee cloned = (Employee) super.clone();
// 此處手動對引用的對象進行了拷貝
cloned.birthday = (Date) birthday.clone();
return cloned;
}
@Override
public String toString() {
return "Employee{" +
"name='" + name + '\'' +
", birthday=" + birthday +
'}';
}
}
// Main函數
public static void main(String[] args) {
try{
Employee em = new Employee();
em.setName("wangyahua");
em.setBirthday(new Date(1990,8,7));
Employee em2 = em.clone();
em2.setName("liqiuhua");
em2.getBirthday().setDate(9);
System.out.println(em);
System.out.println(em2);
}catch (CloneNotSupportedException e){
e.printStackTrace();
}
}
打印結果:
Employee{name=‘wangyahua’, birthday=Sun Sep 07 00:00:00 CST 3890}
Employee{name=‘liqiuhua’, birthday=Tue Sep 09 00:00:00 CST 3890}