第十一条:谨慎的覆盖clone()方法
一个类要想实现克隆,需要实现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()方法的更多相关文章
- Effective Java 之-----谨慎的覆盖clone方法
1.概述 如果clone方法返回一个由构造器创建的对象,它就得到有错误的类.因此,如果覆盖了非final类中的clone方法,则应该返回一个通过调用super.clone得到的对象.如果类的所有超类都 ...
- 第11条:谨慎地覆盖clone
Clone提供一种语言之外的机制:无需调用构造器就可以创建对象. 它的通用约定非常弱: 创建和返回该对象的一个拷贝.这个拷贝的精确含义取决于该对象的类.一般含义是,对于任何对象x,表达式x.clone ...
- Effective Java 第三版——13. 谨慎地重写 clone 方法
Tips <Effective Java, Third Edition>一书英文版已经出版,这本书的第二版想必很多人都读过,号称Java四大名著之一,不过第二版2009年出版,到现在已经将 ...
- Item 11 谨慎地覆盖Clone
1.进行浅拷贝时,只是复制原始数据类型的值,则可以通过覆盖Clone方法来达到.另外,在进行浅拷贝的时候,还要注意,成员对象中不应该要有引用类型,如果有引用类型,那么,进行了浅拷贝之后,两个对象将会共 ...
- [Effective Java 读书笔记] 第三章 对所有对象都通用的方法 第十---十一条
第十条 始终覆盖toString() toString的实现可以使类使用起来更加舒适,在执行println等方法时打印出定制信息. 一单实现了自己的toString,指定输出的固定格式,在方法的文档说 ...
- Java - 谨慎覆盖clone
覆盖clone时需要实现Cloneable接口,Cloneable并没有定义任何方法. 那Cloneable的意义是什么? 如果一个类实现了Clonable,Object的clone方法就可以返回该对 ...
- Effective Java —— 谨慎覆盖clone
本文参考 本篇文章参考自<Effective Java>第三版第十三条"Always override toString",在<阿里巴巴Java开发手册>中 ...
- 谨慎重载clone方法
本文涉及到的概念 1.浅拷贝和深拷贝 2..clone方法的作用和使用方式 3.拷贝构造器和拷贝工厂 1.浅拷贝和深拷贝 浅拷贝 一个类实现Cloneable接口,然后,该类的实例调用clone方 ...
- jquery中的clone()方法使用
clone([Even[,deepEven]]) 描述: 克隆匹配的DOM元素并且选中这些克隆的副本. 在想把DOM文档中元素的副本添加到其他位置时这个函数非常有用. 1:一个布尔值(true 或者 ...
随机推荐
- mybatis快速入门(八)-spring-mybatis动态代理整合
将上一节的代码改造下就好了,不过这一章会加一个basedaomapper.废话不多说直接上代码了. 创建一个BaseDaoMapper.java package cn.my.sm.mapper; /* ...
- 【CF932G】Palindrome Partition(回文树,动态规划)
[CF932G]Palindrome Partition(回文树,动态规划) 题面 CF 翻译: 给定一个串,把串分为偶数段 假设分为了\(s1,s2,s3....sk\) 求,满足\(s_1=s_k ...
- 【BZOJ4569】萌萌哒(并查集,倍增)
[BZOJ4569]萌萌哒(并查集,倍增) 题面 BZOJ 题意: 有一个长度为\(n\)的数 给定\(m\)个限制条件 每次限制\(l1-r1\)与\(l2-r2\)是相同的 求出方案数 题解 如果 ...
- 【洛谷2744 】【CJOJ1804】[USACO5.3]量取牛奶Milk Measuring
题面 Description 农夫约翰要量取 Q(1 <= Q <= 20,000)夸脱(夸脱,quarts,容积单位--译者注) 他的最好的牛奶,并把它装入一个大瓶子中卖出.消费者要多少 ...
- 【NOIP2006】能量项链
题面 Description 在 Mars 星球上,每个 Mars 人都随身佩带着一串能量项链.在项链上有 N 颗能量珠.能量珠是一颗有头标记与尾标记的珠子,这些标记对应着某个正整数.并且,对于相邻的 ...
- HiHocoder1419 : 后缀数组四·重复旋律4&[SPOJ]REPEATS:Repeats
题面 Hihocoder Vjudge Sol 题目的提示说的也非常好 我对求\(LCP(P - L + len \% l, P + len \% L)\)做补充 \(len=LCP(P, P + L ...
- 检测flash是否安装及版本号
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/ ...
- mysql在win10下的卸载
转自http://blog.csdn.net/sxingming/article/details/52601250 本文介绍,在Windows10系统下,如何彻底删除卸载MySQL... 1> ...
- java线程学习第一天__低配版的卖面包机
package Thread;import javax.xml.bind.ValidationEvent;class snacks{ private int SaledSnacks=0; ...
- CentOS7.4安装MySQL踩坑记录
CentOS7.4安装MySQL踩坑记录 time: 2018.3.19 CentOS7.4安装MySQL时网上的文档虽然多但是不靠谱的也多, 可能因为版本与时间的问题, 所以记录下自己踩坑的过程, ...