日期:2011-03-22 16:17:00 来源:本站整理
<b>java克隆的掌握</b>[Java编程]
本文“<b>java克隆的掌握</b>[Java编程]”是由七道奇为您精心收集,来源于网络转载,文章版权归文章作者所有,本站不对其观点以及内容做任何评价,请读者自行判断,以下是其具体内容:
为消除克隆本领,大家大概认为只需将clone()办法简单地设为private(私有)便可,但这样是行不通的,因为不能采取一个底子类办法,并使其在衍生类中更“私有”.所以事情并没有这么简单.此外,我们有必要掌握一个对象能否可以克隆.关于我们计划的一个类,实际有很多种筹划都是可以采纳的:
(1) 保持中立,不为克隆做任何事情.也就是说,固然不可对我们的类克隆,但从它担当的一个类却可按照实际情形决意克隆.只有Object.clone()要对类中的字段举行某些公道的操作时,才可以作这方面的决意.
(2) 支持clone(),采取实现Cloneable(可克隆)本领的尺度操作,并覆盖clone().在被覆盖的clone()中,可调用super.clone(),并捕捉全部违例(这样可以使clone()不“掷”出任何违例).
(3) 有条件地支持克隆.若类包容了其他对象的句柄,而那些对象也答应以克隆(调集类就是这样的一个例子),便可试着克隆拥有对方句柄的全部对象;假如它们“掷”出了违例,只需让这些违例通过便可.举个例子来说,假定有一个特别的Vector,它试图克隆自己包容的全部对象.编写这样的一个Vector时,并不知道客户程序员会把什么情势的对象置入这个Vector中,所以并不知道它们能否真的可以克隆.
(4) 不实现Cloneable(),但是将clone()覆盖成protected,使任何字段都具有精确的复制行为.这样一来,从这个类担当的全部东西都能覆盖clone(),并调用super.clone()来产生精确的复制行为.注意在我们实现筹划里,可以并且应当调用super.clone()——即便那个办法本来预期的是一个Cloneable对象(不然会掷出一个违例),因为没有人会在我们这种范例的对象上直接调用它.它只有通过一个衍生类调用;对那个衍生类来说,假如要保证它正常工作,需实现Cloneable.
(5) 不实现Cloneable来试着避免克隆,并覆盖clone(),以产生一个违例.为使这一假想顺利实现,只有令从它衍生出来的任何类都调用重新定义后的clone()里的suepr.clone().
(6) 将类设为final,从而避免克隆.若clone()还没有被我们的任何一个上级类覆盖,这一假想便不会成功.若已被覆盖,那么再一次覆盖它,并“掷”出一个CloneNotSupportedException(克隆不支持)违例.为担保克隆被禁止,将类设为final是唯一的办法.除此以外,一旦触及保密对象大概碰到想对成立的对象数目举行掌握的其他情形,应当将全部构建器都设为private,并供应一个或更多的特别办法来成立对象.采取这种方法,这些办法便可以限制成立的对象数目以及它们的成立条件——一种特别情形是第16章要介绍的singleton(独子)筹划.
下面这个例子总结了克隆的各种实现办法,然后在层次构造中将其“关闭”:
第一个类Ordinary代表着大家在本书各处最常见到的类:不支持克隆,但在它正式利用今后,却也不由止对其克隆.但假定有一个指向Ordinary对象的句柄,并且那个对象大概是从一个更深的衍生类上溯造型来的,便不能判断它到底能不能克隆.//: CheckCloneable.java // Checking to see if a handle can be cloned // Can't clone this because it doesn't // override clone(): class Ordinary {} // Overrides clone, but doesn't implement // Cloneable: 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: 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(): return duplicate(this); } } // Can't inherit from this, so can't override // the clone method like in BackOn: final class ReallyNoMore extends NoMore {} public class CheckCloneable { static Ordinary tryToClone(Ordinary ord) { String id = ord.getClass().getName(); Ordinary x = null; if(ord instanceof Cloneable) { try { System.out.println("Attempting " + id); x = (Ordinary)((IsCloneable)ord).clone(); System.out.println("Cloned " + id); } catch(CloneNotSupportedException e) { System.out.println( "Could not clone " + id); } } return x; } public static void main(String[] args) { // Upcasting: Ordinary[] ord = { new IsCloneable(), new WrongClone(), new NoMore(), new TryMore(), new BackOn(), new ReallyNoMore(), }; Ordinary x = new Ordinary(); // This won't compile, since clone() is // protected in Object: //! x = (Ordinary)x.clone(); // tryToClone() checks first to see if // a class implements Cloneable: for(int i = 0; i < ord.length; i++) tryToClone(ord[i]); } } ///:~
WrongClone类揭露了实现克隆的一种不精确途径.它确切覆盖了Object.clone(),并将那个办法设为public,但却没有实现Cloneable.所以一旦发出对super.clone()的调用(由于对Object.clone()的一个调用造成的),便会无情地掷出CloneNotSupportedException违例.
在IsCloneable中,大家看到的才是举行克隆的各种精确行动:先覆盖clone(),并实现了Cloneable.但是,这个clone()办法以及本例的别的几个办法并不捕捉CloneNotSupportedException违例,而是任由它通过,并传送给调用者.随后,调用者必须用一个try-catch代码块把它包抄起来.在我们自己的clone()办法中,普通需求在clone()内部捕捉CloneNotSupportedException违例,而不是任由它通过.正如大家今后会理解的那样,对这个例子来说,让它通过是最精确的做法.
类NoMore试图按照Java计划者打算的那样“关闭”克隆:在衍生类clone()中,我们掷出CloneNotSupportedException违例.TryMore类中的clone()办法精确地调用super.clone(),并解析成NoMore.clone(),后者掷出一个违例并禁止克隆.
但在已被覆盖的clone()办法中,假如程序员不服从调用super.clone()的“精确”办法,又会呈现什么情形呢?在BackOn中,大家可看到实际会发生什么.这个类用一个独立的办法duplicate()制作当前对象的一个副本,并在clone()内部调用这个办法,而不是调用super.clone().违例永久不会产生,并且新类是可以克隆的.因此,我们不能依靠“掷”出一个违例的办法来避免产生一个可克隆的类.唯一安全的办法在ReallyNoMore中得到了演示,它设为final,所以不可担当.这意味着假定clone()在final类中掷出了一个违例,便不能通过担当来举行改正,并可有效地禁止克隆(不能从一个拥有肆意担当级数的类中明确调用Object.clone();只能调用super.clone(),它只可拜候直接底子类).因此,只要制作一些触及安全问题的对象,就最好把那些类设为final.
在类CheckCloneable中,我们看到的第一个类是tryToClone(),它能采取任何Ordinary对象,并用instanceof查抄它能否可以克隆.若答案是必定的,就将对象造型成为一个IsCloneable,调用clone(),并将后果造型回Ordinary,最后捕捉有大概产生的任何违例.请注意用运行期范例断定(见第11章)打印出类名,使自己看到发生的一切情形.
在main()中,我们成立了差别范例的Ordinary对象,并在数组定义中上溯造型成为Ordinary.在这之后的头两行代码成立了一个纯粹的Ordinary对象,并试图对其克隆.但是,这些代码不会得到编译,因为clone()是Object中的一个protected(遭到保护的)办法.代码剩余的部份将遍历数组,并试着克隆每个对象,辨别报告它们的成功或失利.输出以下:
总之,假如但愿一个类可以克隆,那么:Attempting IsCloneable Cloned IsCloneable Attempting NoMore Could not clone NoMore Attempting TryMore Could not clone TryMore Attempting BackOn Cloned BackOn Attempting ReallyNoMore Could not clone ReallyNoMore
(1) 实现Cloneable接口
(2) 覆盖clone()
(3) 在自己的clone()中调用super.clone()
(4) 在自己的clone()中捕捉违例
这一系列步骤能到达最抱负的效果.
以上是“<b>java克隆的掌握</b>[Java编程]”的内容,如果你对以上该文章内容感兴趣,你可以看看七道奇为您推荐以下文章:
本文地址: | 与您的QQ/BBS好友分享! |
- ·上一篇文章:副本构建器
- ·下一篇文章:为什么有这个独特的筹划
- ·中查找“<b>java克隆的掌握</b>”更多相关内容
- ·中查找“<b>java克隆的掌握</b>”更多相关内容
评论内容只代表网友观点,与本站立场无关!
评论摘要(共 0 条,得分 0 分,平均 0 分)
查看完整评论