介绍
- 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}