本帖最后由 rexih 于 2015-6-4 17:16 编辑
对象克隆 - 深拷贝与浅拷贝的问题 当拷贝一个类类型变量时,原变量与拷贝变量同时引用同一个对象。改变其中一个变量所引用的对象(的状态)会对另一个变量产生影响
为了复制出一份独立的副本应当使用克隆技术。Object类的clone()方法(浅拷贝),可以判断调用对象的类型,在内存中开辟一块与调用对象大小相同的区域将调用对象的域复制过去。 复制的是域的值,若域为对象变量,并不会将其所引用的对象一同复制,而是原对象和拷贝对象都引用同一个对象,即浅拷贝
深拷贝:覆盖Object的clone方法,在方法中复制可变的对象。
Object类的clone()方法 protected Object clone() throwsCloneNotSupportedException Object类没有实现Cloneable接口,方法是protected,保护权限clone()方法在子类、自定义类无法直接使用,需要覆盖。在构造自定义类时覆盖此方法应当修改为public。
自定义类实现克隆的步骤: 1.声明Cloneable接口 2.覆盖clone()方法 3.覆盖的clone()的权限提升到public 4.返回值修改为自定义类(5.0后协变返回类型) 5.记住抛出CloneNotSupportedException异常 6.调用super.clone()并将返回值强制转换为自定义类 7.深拷贝:单独对可变对象进行克隆,将副本传给新建的自定义类的克隆对象。 8.在使用自定义类的clone()方法时,总记得将返回值强制类型转换为自定义类。
- //有类Person,子类Student,让Person和Student实现克隆
- import java.util.Date;
- class Person implements Cloneable{
- private String name;
- private Date birthday;
- //...
- public Person clone()throws CloneNotSupportedException{
- Person cloned=(Person)super.clone();
- cloned.birthday=(Date)birthday.clone();
- return cloned;
- }
- }
-
- class Student extends Person implements Cloneable{
- private int id;
- //...
- public Student clone() throws CloneNotSupportedException{
- Student cloned=(Student)super.clone();
- cloned.id=id;
- return cloned;
- }
- }
复制代码
除非是final类,否则覆盖的clone()方法不应该捕获CloneNotSupportedException,而是应当抛出。如果不支持克隆,该类可能的子类应当有抛出此异常的选择权 |