Object对象的通用方法-clone

来源:互联网 发布:淘宝怎样开通花呗支付 编辑:程序博客网 时间:2024/05/29 11:35

什么是clone?

GoF设计模式里有一个模式为原型模式,用原型实例指定创建对象的种类,并且通过拷贝这些原型创建新的对象.
简单的说就是clone一个对象实例。使得clone出来的copy和原有的对象一模一样。

clone方法的通用约定非常弱,一般的含义是,对任何对象x,表达式:
x.clone() != x
x.clone().getClass() == x.getClass()
x.clone().equals(x)
但是这些都不是绝对的要求。我们的克隆是:创建它的类的新实例,同时拷贝内部的数据结构。

Object的clone:

堆上的内存存储解释的话(不计内务内存),对一个对象a的clone就是在堆上分配一个和a在堆上所占存储空间一样大的一块地方,然后把a的堆上内存的内容复制到这个新分配的内存空间上。

Object的clone是将对象简单的实行域对域的copy,实例中仅仅拷贝了一个对User的引用,还是指向的同一User对象。即:Shallow clone -默认的浅克隆


为什么需要浅copy?

  1. 效率和简单性,简单的copy一个对象在堆上的的内存比遍历一个对象网然后内存深copy明显效率高并且简单。 
  2. 不给别的类强加意义。如果A实现了Cloneable,同时有一个引用指向B,如果直接复制内存进行深copy的话,意味着B在意义上也是支持Clone的,但是这个是在使用B的A中做的,B甚至都不知道。破坏了B原有的接口。
  3. 有可能破坏语义。如果A实现了Cloneable,同时有一个引用指向B,该B实现为单例模式,如果直接复制内存进行深copy的话,破坏了B的单例模式。
  4. 方便且更灵活,如果A引用一个不可变对象,则内存deep copy是一种浪费。Shadow copy给了程序员更好的灵活性。

怎样去实现clone?

  1. 声明实现Cloneable接口。 否则会抛出CloneNotSupportedException
  2. 调用super.clone拿到一个对象,如果父类的clone实现没有问题的话,在该对象的内存存储中,所有父类定义的field都已经clone好了,该类中的primitive和不可变类型引用也克隆好了,可变类型引用都是浅copy。
  3. 把浅copy的引用指向原型对象新的克隆体。(拷贝任何包含内部"深层结构"的可变对象,并用指向新对象的引用代替原来指向这些对象的引用)
  4. 注:shallow clone还是deep clone主要取决于对象的域是什么性质的。如果是基本类型或不可变引用类型(如:String),就应该用shallow clone,其他引用类型用deep clone




0 0