======================================================
注:本文源代码点此下载
======================================================
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:
要添加克隆功能到一个类,我们一共有三个步骤要做
object基类中的clone方法为protected类型,我们必须override子类中的clone方法,改变访问权限为public,否则此方法还是在子类中不可见。
在子类的clone方法中写super.clone(),先执行父类的clone然后在执行自己添加的东西。
实现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 {}
} ///:~
======================================================
在最后,我邀请大家参加新浪APP,就是新浪免费送大家的一个空间,支持PHP+MySql,免费二级域名,免费域名绑定 这个是我邀请的地址,您通过这个链接注册即为我的好友,并获赠云豆500个,价值5元哦!短网址是http://t.cn/SXOiLh我创建的小站每天访客已经达到2000+了,每天挂广告赚50+元哦,呵呵,饭钱不愁了,\(^o^)/