Java clone

Why Clone? : 

 primitive类型是pass by value,  而Object类型是pass by reference.  所谓reference就是object所在的内存地址,  如果我们把一个object作为参数传给方法,我们实际上传递的是"object所在内存地址的copy"。相反的,如果传递的是primitive reference, 则是它本身的copy. 一般来讲,方法是用来改变或者返回"他所在object"的state,  但是有时候我们也会想要改变 "传到方法里面的object" 的状态, 但是同时不想影响方法外的那个原始"object" ,我们就需要做一个local copy.


Type of Clone 

分为Deep copy 和 Shallow copy两种,  与后者相比, Deep copy不但copy目标object,而且把目标object的references指向的object也全做了copy.

Add Cloneability to a Class 

要添加克隆功能到一个类,我们一共有三个步骤要做

  1. Object基类中的clone方法为protected类型,我们必须override子类中的clone方法,改变访问权限为public,否则此方法还是在子类中不可见。
  2. 在子类的clone方法中写super.clone(),先执行父类的clone然后在执行自己添加的东西。
  3. 实现Cloneable接 口,这是一个空接口(tagging interface), 存在的目的在于确定clone方法是否应该扔出CloneNotSupportedException. 如果我们没有实现这个接口,则调用clone方法的时候,一定会收到一个异常。 另外一个功能就是,可以对一群对象用instanceof来确定他们是否可以被克隆。

Clone的继承以及关闭:  

在一个类中定义了clone功能之后,其子类也会有克隆功能,但是我们可以随时"turn off"这个功能


"Final", Turn Off clone() For Ever! :  

不能指望“抛出异常”关闭一个类的子类的克隆能力,因为子类可以通过重载重新turn on克隆能力,最好的方法就是用final,这样子子类就无法重载clone()方法,子类得到的永远是抛出“无法克隆的异常”的父类方法。


Code Example from  《Thinking in Java 3rd》

// Can't clone this because it doesn't override clone():
class Ordinary {}

// Overrides clone, but doesn't implement Cloneable, will get exception:
class WrongClone extends Ordinary {
public Object clone() throws CloneNotSupportedException {
return super.clone(); // Throws exception
}
}

// Does all the right things for cloning:
class IsCloneable extends Ordinary implements Cloneable {
public Object clone() throws CloneNotSupportedException {
return super.clone();
}
}

// Turn off cloning by throwing the exception, throw a new exception
// within the clone() method rather than calling super.clone():
class NoMore extends IsCloneable {
public Object clone() throws CloneNotSupportedException {
throw new CloneNotSupportedException();
}
}

class TryMore extends NoMore {
public Object clone() throws CloneNotSupportedException {
// Calls NoMore.clone(), throws exception:
return super.clone();
}
}

class BackOn extends NoMore {
private BackOn duplicate(BackOn b) {
// Somehow make a copy of b and return that copy.
// This is a dummy copy, just to make the point:
return new BackOn();
}
public Object clone() {
// Doesn't call NoMore.clone(), but does the same thing.
return duplicate(this);
}
}

// You can't inherit from this, so you can't override
// the clone method as you can in BackOn:
final class ReallyNoMore extends NoMore {}

}
///:~

posted on 2011-04-29 12:37  廉帅博  阅读(910)  评论(0编辑  收藏  举报