Effective Java读书笔记之clone方法
来源:互联网 发布:太阳能电池知乎 编辑:程序博客网 时间:2024/05/17 05:52
我们都知道Java中所有的类都继承自Object类,Object类中实现了一个clone方法。按照常理来推断,它应该就是对类中的field进行copy一下然后返回就好了。但是Java的实现很奇葩,它首先检查当前类是不是实现了Cloneable接口,如果实现了,才进行clone这个操作,否则跑出CloneNotSupportedException,而且这个clone方法还是protected。因此,如果我们需要定义一个提供clone方法的类,需要干以下几件事:
- 实现Cloneable接口
- 将clone方法变成public,一个最基本的实现如下:
public class A implements Cloneable{private Object obj;@Overridepublic A clone(){return (A)super.clone();}}
以上的实现有几点问题:
- 首先就是deep copy的问题,如:
A b1 = new A();A b2 = b1.clone();System.out.println(b1.objA == b2.objA); // true
这显然不是我们想看到的,因为a2.obj的改变会导致a1.obj的改变,因此上述方法应该改为
public class A implements Cloneable{ private Object obj; public A clone() throws CloneNotSupportedException {A a = (A) super.clone();if (obj != null) a.obj = new Object();return a; }}
当然对于不同的filed我们需要不同的clone方法。 - 其次,对于那些被设计于用于被继承类,我们应该这样实现:
class A{ Object objA; protected A clone() throws CloneNotSupportedException {A a = (A) super.clone();if (objA != null) a.objA = new Object();return a; }}class B extends A implements Cloneable{ Object objB; public B clone() throws CloneNotSupportedException {B b = (B) super.clone();if (objB != null) b.objB = new Object();return b; }}
也就是说,不要实现Cloneable接口,将clone方法保持protected的访问权限,这样就给了子类是否要实现clone的选择权。 - 最后,我们在实现clone方法的时候应该遵循以下几个契约:
x.clone() != x //克隆出的object应该与被克隆的object独立x.clone().getClass() == x.getClass() //克隆出来的对象应该与源对象同类x.clone().equals(x) //克隆出的对象应该与源对象equal
Object类中的clone方法是用native方法实现的,而且那个Cloneable接口的使用方法也挺奇葩,它是作为一个标识而不是定义类的责任而存在的,因此书中建议如果我们要提供clone类似的功能,我们可以像C++中的那样提供copy构造函数,或者提供一个静态的copy方法,这样比较优雅和安全。这样做唯一的坏处就是要自己多写几行代码进行field到field的copy。
- Effective Java读书笔记之clone方法
- 《Effective Java》读书笔记09--谨慎地覆盖clone方法
- 十月读书笔记:Effective Java(五)--clone和toString方法
- Effective.Java 读书笔记(11)关于clone方法
- Effective Java读书笔记-谨慎的覆盖clone
- Effective Java读书笔记六:方法
- 读书笔记-《Effective java 》之 考虑静态方法代替构造器
- 《Effective java》读书笔记之二
- 《Effective java》读书笔记之二
- 学习effective java-11对所有对象共同的方法之覆写clone方法时请慎重考虑
- JAVA学习之 Effective JAVA (读书笔记)
- Effective Java 读书笔记之java 序列化
- Effective Java读书笔记(二):方法、通用程序设计
- 【读书笔记】《Effective Java》(6)--方法
- effective java 读书笔记---第7章 方法
- 【effective Java读书笔记】方法(一)
- 【effective Java读书笔记】方法(二)
- 【effective Java读书笔记】方法(三)
- java 递归模式 遍历给定文件
- StackOverflow 并不只是一个问答网站
- CMD命令工具--Windows下使用tree命令生成目录
- 修改Android解锁界面
- 多线程
- Effective Java读书笔记之clone方法
- 淘宝京东类电商评论标签化的思路
- acfsutil size: ACFS-03008: The volume could not be resized
- [copy]CA认证学习笔记
- 在不使用if,while,do...while,for,switch,?:等操作,实现函数void printLess(int k),返回小于k的所有整数
- 程序员面试、算法研究、编程艺术、红黑树、数据挖掘5大系列集锦
- 【百为学习板】 例程1- LED流水灯
- C# 流概括
- 初用hibernate和struts2结合时的总结