(11):谨慎的覆盖clone
来源:互联网 发布:百度贴吧网络连接失败 编辑:程序博客网 时间:2024/05/01 23:05
当我们想要克隆一个对象时,也就是说我们想要两个一模一样的对象,但想要这两个对象各自开辟空间的时候,我们通常要实现cloneable接口。但是接口没给我们提供clone的实现,但Object类却给我们提供了一个受保护的clone实现。
一般来讲我们直接在子类重写的clone方法调用super,clone()可以得到我们想要的结果。
import java.util.Date;public class User implements Cloneable {private String username;private String password;private Date birthdate;public User(String username, String password, Date birthdate) {this.username = username;this.password = password;this.birthdate = birthdate;}@Overrideprotected Object clone() throws CloneNotSupportedException {return super.clone();}@Overridepublic int hashCode() {// 省略equals的实现(可用eclipse自动生成)}@Overridepublic boolean equals(Object obj) {// 省略equals的实现(可用eclipse自动生成)}// 省略一大堆get/set方法}
import java.util.Date;import org.junit.Test;public class TestCase {@Testpublic void testUserClone() throws CloneNotSupportedException {User u1 = new User("Kent", "123456", new Date());User u2 = u1;User u3 = (User) u1.clone();System.out.println(u1 == u2);// trueSystem.out.println(u1.equals(u2));// trueSystem.out.println(u1 == u3);// falseSystem.out.println(u1.equals(u3));// true}}
如上诉例子所示,我们得到了我们预期的结果,但也有时结果会和预期相去甚远。
public class Administrator implements Cloneable {private User user;private Boolean editable;public Administrator(User user, Boolean editable) {this.user = user;this.editable = editable;}@Overrideprotected Object clone() throws CloneNotSupportedException {return super.clone();}@Overridepublic int hashCode() {// 老规矩}@Overridepublic boolean equals(Object obj) {// 老规矩}// 老规矩}
import java.util.Date;import org.junit.Test;public class TestCase {@Testpublic void testAdministratorClone() throws CloneNotSupportedException {Administrator a1 = new Administrator(new User("Kent", "123456", new Date()), true);Administrator a2 = a1;Administrator a3 = (Administrator) a1.clone();System.out.println(a1 == a2);// trueSystem.out.println(a1.equals(a2));// trueSystem.out.println(a1 == a3);// falseSystem.out.println(a1.equals(a3));// trueSystem.out.println(a1.getUser() == a3.getUser());//true ! It's not our expected!!!!!System.out.println(a1.getUser().equals(a3.getUser()));//true}}这里我们就可以引入两个专业的术语:浅克隆(shallow clone)和深克隆(deep clone)。
所谓的浅克隆,顾名思义就是很表面的很表层的克隆,如果我们要克隆Administrator对象,只克隆他自身以及他包含的所有对象的引用地址。
而深克隆,就是非浅克隆。克隆除自身以外所有的对象,包括自身所包含的所有对象实例。至于深克隆的层次,由具体的需求决定,也有“N层克隆”一说。
但是,所有的基本(primitive)类型数据,无论是浅克隆还是深克隆,都会进行原值克隆。毕竟他们都不是对象,不是存储在堆中。注意:基本数据类型并不包括他们对应的包装类。
如果我们想让对象进行深度克隆,我们可以这样修改Administrator类。
@Overrideprotected Object clone() throws CloneNotSupportedException {Administrator admin = (Administrator) super.clone();admin.user = (User) admin.user.clone();return admin;}简而言之,所有实现了Cloneable接口的类都应该有一个公有的类覆盖clone。此方法先调用super. clone,然后修正需要修正的域。cloneable有很多问题,我们可以使用拷贝构造器或者拷贝工厂去代替它。
public Yum(Yum yum);public static Yum newInstance(Yum yum)这两个做法都比实现Cloneable接口具有更多优势。事实上许多专家级的程序员重来不去覆盖clone()方法也重来不去调用它。
0 0
- (11):谨慎的覆盖clone
- 谨慎的覆盖clone
- 第11条:谨慎的覆盖clone
- effective java (11) 谨慎地覆盖clone
- Effective Java读书笔记-谨慎的覆盖clone
- 第11条:谨慎地覆盖clone
- 第11条:谨慎地覆盖clone
- 第11条:谨慎地覆盖clone
- 谨慎地覆盖clone。
- effective java(11) 之谨慎地覆盖clone
- 第十一条 谨慎地覆盖clone
- 第十一条:谨慎地覆盖clone方法
- 10-谨慎的改写clone
- Effective Java 对于所用对象都通用的方法 11.谨慎地覆盖clone
- 《Effective java》读书记录-第11条-谨慎地覆盖clone
- 《Effective Java》读书笔记09--谨慎地覆盖clone方法
- Effective Java之谨慎地覆盖clone(十一)
- 第10条:谨慎地改写clone
- gulp部分文档
- Windows 7下安装Scrapy问题的解决方法记录
- 堆栈实现汉诺塔
- 2015年第六届蓝桥杯C/C++程序设计本科B组省赛-星系炸弹(结果填空)
- Delphi 从 TWebBrowser中获得当前输入处的链接
- (11):谨慎的覆盖clone
- JDBC结合JSP使用
- Maven的生命周期
- linux:操作系统 OS 基本操作,来自黑马程序员老师总结
- 关于脚本语言PERL的两个笔记(编码问题,未完全解决)
- Android studio下载与安装
- SpringMVC 重定向
- 一 javase学习记录07
- IBM高级工程师谈数据湖管理