一个类要想实现克隆,需要实现Cloneable接口,表明这个类的对象具有克隆的功能。

Cloneable接口是一个mixin接口,它里面并没有任何的抽象方法,类似的接口有Serializable接口,表明该类的对象可以序列化。

首先应该明确通过一个对象克隆出另一个对象的概念:通过一个对象克隆出另一个对象,简称对象1和对象2,这两个对象就成为两个独立的对象,

那么对对象1做任何的修改,对象2应该不受影响;对对象2做任何的修改的,对象1就不应该受影响。这样就要求对象1与对象2的实例域各自是独立的。

那么我们知道一个对象的实例域,包括基本类型(int,long..等等)的域,引用类型的域(分为可变的域和final不可变的域)。

现在了解Object类的clone()方法:

protected native Object clone() throws CloneNotSupportedException;

clone()方法是一个受保护的本地方法。

clone()方法的通用约束如下:

x.clone() != x        应该返回true

x.clone().getClass() == x.getClass()        应该返回true

x.clone().equals(x)           应该返回true

对于实现了Cloneable()接口的类,也就是具有克隆能力的类,我们总是期望它提供一个功能适当的公有的clone()方法。

如果我们在一个类的clone()方法只调用super.clone(),然后返回,它仅仅是返回了一个新的对象,这个对象具有和原对象一样的基本类型域,

但是这个对象的引用类型域引用的对象还是原对象的引用类型域所引用的对象。这样就导致一个问题,对原对象引用类型的域所做的修改会影响

到新对象的引用类型域。     也就是说调用Object类的克隆方法,仅仅完成了新对象的创建,和基本类型域的克隆,但是引用类型域的引用还是

指向了旧对象的引用类型域的实例。如下图:

但是有一种情况允许出现这样的克隆,这个类引用类型域只有final不可变类型。 因为对象1的final引用类型域只要引用到了实例,就不允许再改变。

这样对象1的域要改变也只有基本类型域了,而基本类型域我们已经完成了克隆。

简而言之,所有实现了Cloneable接口的类都应该有一个公有的方法覆盖从Object类继承而来的clone()方法,此公有方法先调用super.clone(),

得到一个“浅拷贝”的对象,然后根据原对象的实例域的情况,修正任何需要修正的域。一般情况下,这意味这要拷贝任何包含内部“深层结构”

的可变对象。并将新对象的引用代替原来指向这些对象的引用。虽然,这些内部拷贝操作往往可以通过层层递进的调用clone()来完成(要求图中的

Apple类和Dog类也必须正确的提供公有的clone()方法),但这通常不是最佳的方法。如果该类只包含基本类型的域,和不可变类型的引用域,

那么多半情况下是没有域需要修正的。

第十一条:谨慎的覆盖clone()方法的更多相关文章

  1. Effective Java 之-----谨慎的覆盖clone方法

    1.概述 如果clone方法返回一个由构造器创建的对象,它就得到有错误的类.因此,如果覆盖了非final类中的clone方法,则应该返回一个通过调用super.clone得到的对象.如果类的所有超类都 ...

  2. 第11条:谨慎地覆盖clone

    Clone提供一种语言之外的机制:无需调用构造器就可以创建对象. 它的通用约定非常弱: 创建和返回该对象的一个拷贝.这个拷贝的精确含义取决于该对象的类.一般含义是,对于任何对象x,表达式x.clone ...

  3. Effective Java 第三版——13. 谨慎地重写 clone 方法

    Tips <Effective Java, Third Edition>一书英文版已经出版,这本书的第二版想必很多人都读过,号称Java四大名著之一,不过第二版2009年出版,到现在已经将 ...

  4. Item 11 谨慎地覆盖Clone

    1.进行浅拷贝时,只是复制原始数据类型的值,则可以通过覆盖Clone方法来达到.另外,在进行浅拷贝的时候,还要注意,成员对象中不应该要有引用类型,如果有引用类型,那么,进行了浅拷贝之后,两个对象将会共 ...

  5. [Effective Java 读书笔记] 第三章 对所有对象都通用的方法 第十---十一条

    第十条 始终覆盖toString() toString的实现可以使类使用起来更加舒适,在执行println等方法时打印出定制信息. 一单实现了自己的toString,指定输出的固定格式,在方法的文档说 ...

  6. Java - 谨慎覆盖clone

    覆盖clone时需要实现Cloneable接口,Cloneable并没有定义任何方法. 那Cloneable的意义是什么? 如果一个类实现了Clonable,Object的clone方法就可以返回该对 ...

  7. Effective Java —— 谨慎覆盖clone

    本文参考 本篇文章参考自<Effective Java>第三版第十三条"Always override toString",在<阿里巴巴Java开发手册>中 ...

  8. 谨慎重载clone方法

    本文涉及到的概念 1.浅拷贝和深拷贝 2..clone方法的作用和使用方式 3.拷贝构造器和拷贝工厂   1.浅拷贝和深拷贝 浅拷贝 一个类实现Cloneable接口,然后,该类的实例调用clone方 ...

  9. jquery中的clone()方法使用

    clone([Even[,deepEven]]) 描述: 克隆匹配的DOM元素并且选中这些克隆的副本. 在想把DOM文档中元素的副本添加到其他位置时这个函数非常有用. 1:一个布尔值(true 或者 ...

随机推荐

  1. C#中string类型是值类型还是引用类型?

    .Net框架程序设计(修订版)中有这样一段描述:String类型直接继承自Object,这使得它成为一个引用类型,也就是说线程上的堆栈上不会驻留有任何字符串. string类型(引用类型) 名称 CT ...

  2. VS2013 图片背景·全透明背景图(转)

    Note: 1.xaml编辑器和个别的编辑器(如HTML的)因为是承载在VS的一个子窗口上,所以背景依然是黑色的. 2.该背景必须在VS实验环境下使用. 效果图: 1.准备工作 1.先准备Visual ...

  3. 公网访问阿里云数据库MongoDB——填坑日记

    业务情景 两台服务器,一台阿里云ECS云服务器(专用网络),另一台是阿里云数据库MongoDB,处于安全考虑MongoDB是不运行外网连接的,那接下来就看怎么实现公网访问. 看到上面红色的网络类型描述 ...

  4. css3动画结束捕捉事件整理

    //捕捉webkitAnimationEnd事件 element.addEventListener('webkitAnimationEnd', end, false); //捕捉webkitTrans ...

  5. BZOJ2693jzptab

    简单般Bzoj2154: Crash的数字表格 Sol 增加了数据组数T<=10000 推到 \(ans=\sum_{d=1}^{N}d*\sum_{i=1}^{\lfloor\frac{N}{ ...

  6. iOS开发——iOS国际化 APP内语言切换

    最近一个一直在迭代的老项目收到一份新的开发需求,项目需要做国际化适配,简体中文+英文.由于项目中采用了storyboard和纯代码两种布局方式,所以国际化也要同时实现.上网查了些资料,实现了更改系统语 ...

  7. NancyFX 第九章 Responses(响应对象)

    和内容协商最最为紧密的当属Nancy的Response对象. 在本书的第一张你应该就已经看到过Response对象,之前是使用它的AsFile 方法返回一个简单文件. using Nancy; nam ...

  8. java 多态 ---父类调用子类方法

    package test1;//多态的体现import javax.print.attribute.standard.RequestingUserName;import java.util.Scann ...

  9. 负载均衡,会话保持,session同步(转)

    转自:http://bbs.linuxtone.org/thread-18212-1-1.html 一,什么负载均衡一个新网站是不要做负载均衡的,因为访问量不大,流量也不大,所以没有必要搞这些东西.但 ...

  10. windows中安装redis

    Redis是有名的NoSql数据库,一般Linux都会默认支持.但在Windows环境中, Windows的Redis安装包需要到以下GitHub链接找到.链接:https://github.com/ ...