ImageVerifierCode 换一换
格式:DOCX , 页数:5 ,大小:19.57KB ,
资源ID:4627324      下载积分:3 金币
快捷下载
登录下载
邮箱/手机:
温馨提示:
快捷下载时,用户名和密码都是您填写的邮箱或者手机号,方便查询和重复下载(系统自动生成)。 如填写123,账号就是123,密码也是123。
特别说明:
请自助下载,系统不会自动发送文件的哦; 如果您已付费,想二次下载,请登录后访问:我的下载记录
支付方式: 支付宝    微信支付   
验证码:   换一换

加入VIP,免费下载
 

温馨提示:由于个人手机设置不同,如果发现不能下载,请复制以下地址【https://www.bdocx.com/down/4627324.html】到电脑端继续下载(重复下载不扣费)。

已注册用户请登录:
账号:
密码:
验证码:   换一换
  忘记密码?
三方登录: 微信登录   QQ登录  

下载须知

1: 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。
2: 试题试卷类文档,如果标题没有明确说明有答案则都视为没有答案,请知晓。
3: 文件的所有权益归上传用户所有。
4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
5. 本站仅提供交流平台,并不能对任何下载内容负责。
6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

版权提示 | 免责声明

本文(JAVA克隆对象CLONE的用法和作用 电脑资料.docx)为本站会员(b****4)主动上传,冰豆网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对上载内容本身不做任何修改或编辑。 若此文所含内容侵犯了您的版权或隐私,请立即通知冰豆网(发送邮件至service@bdocx.com或直接QQ联系客服),我们立即给予删除!

JAVA克隆对象CLONE的用法和作用 电脑资料.docx

1、JAVA克隆对象CLONE的用法和作用 电脑资料java克隆对象clone()的用法和作用 电脑资料 假设需修改一个对象,同时不想改变调用者的对象,就要制作该对象的一个本地副本, 假设需修改一个对象,同时不想改变调用者的对象,就要制作该对象的一个本地副本。这也是本地副本最常见的一种用途。假设决定制作一个本地副本,只需简单地使用clone()方法即可。Clone是“克隆”的意思,即制作完全一模一样的副本。这个方法在根底类Object中定义成“protected”(受保护)模式。但在希望克隆的任何衍生类中,必须将其覆盖为“public”模式。例如,标准库类Vector覆盖了clone(),所以能为

2、Vector调用clone(),如下所示: clone()方法产生了一个Object,后者必须立即重新造型为正确类型。这个例子指出Vector的clone()方法不能自动尝试克隆Vector内包含的每个对象由于别名问题,老的Vector和克隆的Vector都包含了相同的对象。我们通常把这种情况叫作“简单 ”或者“浅层 ”,因为它只 了一个对象的“外表”局部。实际对象除包含这个“外表”以外,还包括句柄指向的所有对象,以及那些对象又指向的其他所有对象,由此类推。这便是“对象网”或“对象关系网”的由来。假设能 下所有这张网,便叫作“全面 ”或者“深层 ”。 在输出中可看到浅层 的结果,注意对v2采取

3、的行动也会影响到v: 一般来说,由于不敢保证Vector里包含的对象是“可以克隆”(注释)的,所以最好不要试图克隆那些对象。 尽管克隆方法是在所有类最根本的Object中定义的,但克隆仍然不会在每个类里自动进行。这似乎有些 ,因为根底类方法在衍生类里是肯定能用的。但Java确实有点儿反其道而行之;如果想在一个类里使用克隆方法,唯一的方法就是专门添加一些代码,以便保证克隆的正常进行。 使用protected时的技巧 为防止我们创立的每个类都默认具有克隆能力,clone()方法在根底类Object里得到了“保存”(设为protected)。这样造成的后果就是:对那些简单地使用一下这个类的客户程序员

4、来说,他们不会默认地拥有这个方法;其次,我们不能利用指向根底类的一个句柄来调用clone()(尽管那样做在某些情况下特别有用,比方用多形性的方式克隆一系列对象)。在编译期的时候,这实际是通知我们对象不可克隆的一种方式而且最奇怪的是,Java库中的大多数类都不能克隆。因此,假设我们执行下述代码: Integer x = new Integer(l); x = x.clone(); 那么在编译期,就有一条讨厌的错误弹出,告诉我们不可访问clone()因为Integer并没有覆盖它,而且它对protected版本来说是默认的)。 但是,假假设我们是在一个从Object衍生出来的类中(所有类都是从Ob

5、ject衍生的),就有权调用Object.clone(),因为它是“protected”,而且我们在一个继承器中。根底类clone()提供了一个有用的功能它进行的是对衍生类对象的真正“按位” ,所以相当于标准的克隆行动。然而,我们随后需要将自己的克隆操作设为public,否那么无法访问。总之,克隆时要注意的两个关键问题是:几乎肯定要调用super.clone(),以及注意将克隆设为public。 有时还想在更深层的衍生类中覆盖clone(),否那么就直接使用我们的clone()(现在已成为public),而那并不一定是我们所希望的(然而,由于Object.clone()已制作了实际对象的一个副

6、本,所以也有可能允许这种情况)。protected的技巧在这里只能用一次:首次从一个不具备克隆能力的类继承,而且想使一个类变成“能够克隆”。而在从我们的类继承的任何场合,clone()方法都是可以使用的,因为Java不可能在衍生之后反而缩小方法的访问范围。换言之,一旦对象变得可以克隆,从它衍生的任何东西都是能够克隆的,除非使用特殊的机制(后面讨论)令其“关闭”克隆能力。 实现Cloneable接口 为使一个对象的克隆能力功成圆满,还需要做另一件事情:实现Cloneable接口。这个接口使人稍觉奇怪,因为它是空的! inte Cloneable 之所以要实现这个空接口,显然不是因为我们准备上溯造

7、型成一个Cloneable,以及调用它的某个方法。有些人认为在这里使用接口属于一种“欺骗”行为,因为它使用的特性打的是别的主意,而非原来的意思。Cloneable inte 的实现扮演了一个标记的角色,封装到类的类型中。 两方面的原因促成了Cloneable inte 的存在。首先,可能有一个上溯造型句柄指向一个根底类型,而且不知道它是否真的能克隆那个对象。在这种情况下,可用instan of关键字(第11章有介绍)调查句柄是否确实同一个能克隆的对象连接: if(myHandle instan of Cloneable) / 第二个原因是考虑到我们可能不愿所有对象类型都能克隆。所以Object

8、.clone()会验证一个类是否真的是实现了Cloneable接口。假设答案是否认的,那么“掷”出一个CloneNotSupportedEx ption违例。所以在一般情况下,我们必须将“implement Cloneable”作为对克隆能力提供支持的一局部。 理解了实现clone()方法背后的所有细节后,便可创立出能方便 的类,以便提供了一个本地副本: 不管怎样,clone()必须能够访问,所以必须将其设为public(公共的)。其次,作为clone()的初期行动,应调用clone()的根底类版本。这里调用的clone()是Object内部预先定义好的。之所以能调用它,是由于它具有prote

9、cted(受到保护的)属性,所以能在衍生的类里访问。 Object.clone()会检查原先的对象有多大,再为新对象腾出足够多的内存,将所有二进制位从原来的对象 到新对象。这叫作“按位 ”,而且按一般的想法,这个工作应该是由clone()方法来做的。但在Object.clone()正式开始操作前,首先会检查一个类是否Cloneable,即是否具有克隆能力换言之,它是否实现了Cloneable接口。假设未实现,Object.clone()就掷出一个CloneNotSupportedEx ption违例,指出我们不能克隆它。因此,我们最好用一个try-catch块将对super.clone()的调

10、用代码包围(或封装)起来,试图捕获一个应当永不出现的违例(因为这里确实已实现了Cloneable接口)。 在LocalCopy中,两个方法g()和f()揭示出两种参数传递方法间的差异。其中,g()演示的是按引用传递,它会修改外部对象,并返回对那个外部对象的一个引用。而f()是对自变量进行克隆,所以将其别离出来,并让原来的对象保持 。随后,它继续做它希望的事情。甚至能返回指向这个新对象的一个句柄,而且不会对原来的对象产生任何副作用。注意下面这个多少有些乖僻的语句: v = (MyObject)v.clone(); 它的作用正是创立一个本地副本。为防止被这样的一个语句搞混淆,记住这种相当奇怪的编码

11、形式在Java中是完全允许的,因为有一个名字的所有东西实际都是一个句柄。所以句柄v用于克隆一个它所指向的副本,而且最终返回指向根底类型Object的一个句柄(因为它在Object.clone()中是那样被定义的),随后必须将其造型为正确的类型。 在 in()中,两种不同参数传递方式的区别在于它们分别测试了一个不同的方法。输出结果如下: 大家要记住这样一个事实:Java对“是否等价”的测试并不对所比拟对象的内部进行检查,从而核实它们的值是否相同。=和!=运算符只是简单地比照句柄的内容。假设句柄内的地址相同,就认为句柄指向同样的对象,所以认为它们是“等价”的。所以运算符真正检测的是“由于别名问题,

12、句柄是否指向同一个对象?” 调用Object.clone()时,实际发生的是什么事情呢?当我们在自己的类里覆盖clone()时,什么东西对于super.clone()来说是最关键的呢?根类中的clone()方法负责建立正确的存储容量,并通过“按位 ”将二进制位从原始对象中 到新对象的存储空间。也就是说,它并不只是预留存储空间以及 一个对象实际需要调查出欲 之对象的准确大小,然后 那个对象。由于所有这些工作都是在由根类定义之clone()方法的内部代码中进行的(根类并不知道要从自己这里继承出去什么),所以大家或许已经猜到,这个过程需要用RTTI判断欲克隆的对象的实际大小。采取这种方式,clone

13、()方法便可建立起正确数量的存储空间,并对那个类型进行正确的按位 。 不管我们要做什么,克隆过程的第一个局部通常都应该是调用super.clone()。通过进行一次准确的 ,这样做可为后续的克隆进程建立起一个良好的根底。随后,可采取另一些必要的操作,以完成最终的克隆。 为确切了解其他操作是什么,首先要正确理解Object.clone()为我们带来了什么。特别地,它会自动克隆所有句柄指向的目标吗?下面这个例子可完成这种形式的检测: 一条Snake(蛇)由数段构成,每一段的类型都是Snake, increment()方法的作用是循环递增每个标记,使我们能看到发生的变化;而toString那么循环打

14、印出每个标记。输出如下: s = :a:b:c:d:e s2 = :a:b:c:d:e after s.increment, s2 = :a:c:d:e:f 这意味着只有第一段才是由Object.clone() 的,所以此时进行的是一种“浅层 ”。假设希望 整条蛇即进行“深层 ”必须在被覆盖的clone()里采取附加的操作。 通常可在从一个能克隆的类里调用super.clone(),以确保所有根底类行动(包括Object.clone())能够进行。随着是为对象内每个句柄都明确调用一个clone();否那么那些句柄会别名变成原始对象的句柄。构建器的调用也大致相同首先构造根底类,然后是下一个衍生的

15、构建器以此类推,直到位于最深层的衍生构建器。区别在于clone()并不是个构建器,所以没有方法实现自动克隆。为了克隆,必须由自己明确进行。 试图深层 合成对象时会遇到一个问题。必须假定成员对象中的clone()方法也能依次对自己的句柄进行深层 ,以此类推。这使我们的操作变得复杂。为了能正常实现深层 ,必须对所有类中的代码进行控制,或者至少全面掌握深层 中需要涉及的类,确保它们自己的深层 能正确进行。 下面这个例子了面对一个合成对象进行深层 时需要做哪些事情: DepthReading和TemperatureReading非常相似;它们都只包含了根本数据类型。所以clone()方法能够非常简单:

16、调用super.clone()并返回结果即可。注意两个类使用的clone()代码是完全一致的。 O anReading是由DepthReading和TemperatureReading对象合并而成的。为了对其进行深层 ,clone()必须同时克隆O anReading内的句柄。为到达这个目标,super.clone()的结果必须造型成一个O anReading对象(以便访问depth和temperature句柄)。 java.lang.Object里面有一个方法clone() protected Object clone() throws CloneNotSupportedEx ption创立

17、并返回此对象的一个副本。“副本”的准确含义可能依赖于对象的类。这样做的目的是,对于任何对象 x,表达式: x.clone() != x为 true,表达式: x.clone().getClass() = x.getClass()也为 true,但这些并非必须要满足的要求。一般情况下: x.clone().equals(x)为 true,但这并非必须要满足的要求。 按照惯例,返回的对象应该通过调用 super.clone 获得。如果一个类及其所有的超类(Object 除外)都遵守此约定,那么 x.clone().getClass() = x.getClass()。 按照惯例,此方法返回的对象应该

18、 于该对象(正被 的对象)。要获得此 性,在 super.clone 返回对象之前,有必要对该对象的一个或多个字段进行修改。这通常意味着要 包含正在被 对象的内部“深层结构”的所有可变对象,并使用对副本的引用替换对这些对象的引用。如果一个类只包含根本字段或对不变对象的引用,那么通常不需要修改 super.clone 返回的对象中的字段。 Object 类的 clone 方法执行特定的 操作。首先,如果此对象的类不能实现接口 Cloneable,那么会抛出 CloneNotSupportedEx ption。注意,所有的数组都被视为实现接口 Cloneable。否那么,此方 创立此对象的类的一个新实例,并像通过分配那样,严格使用此对象相应字段的内容初始化该对象的所有字段;这些字段的内容没有被自我 。所以,此方法执行的是该对象的“浅表 ”,而不“深层 ”操作。 Object 类本身不实现接口 Cloneable,所以在类为 Object 的对象上调用 clone 方法将会导致在运行时抛出异常。 返回: 此实例的一个副本。 抛出: CloneNotSupportedEx ption - 如果对象的类不支持 Cloneable 接口,那么重写 clone 方法的子类也会抛出此异常,以指示无法 某个实例。 运行结果如下: 模板,内容仅供参考

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1