快速业务通道

java的clone实现 - 编程入门网

作者 佚名技术 来源 NET编程 浏览 发布时间 2012-06-26

java的clone实现

时间:2007-05-29 yycnet.yeah.net yyc译 理解了实现clone()方法背后的所有细节后,便可创建出能方便复制的类,以便提供了一个本地副本:
//: LocalCopy.java
// Creating local copies with clone()
import java.util.*;

class MyObject implements Cloneable {
  int i;
  MyObject(int ii) { i = ii; }
  public Object clone() {
    Object o = null;
    try {
      o = super.clone();
    } catch (CloneNotSupportedException e) {
      System.out.println("MyObject can''t clone");
    }
    return o;
  }
  public String toString() {
    return Integer.toString(i);
  }
}

public class LocalCopy {
  static MyObject g(MyObject v) {
    // Passing a handle, modifies outside object:
    v.i++;
    return v;
  }
  static MyObject f(MyObject v) {
    v = (MyObject)v.clone(); // Local copy
    v.i++;
    return v;
  }
  public static void main(String[] args) {
    MyObject a = new MyObject(11);
    MyObject b = g(a);
    // Testing handle equivalence,
    // not object equivalence:
    if(a == b) 
      System.out.println("a == b");
    else 
      System.out.println("a != b");
    System.out.println("a = " + a);
    System.out.println("b = " + b);
    MyObject c = new MyObject(47);
    MyObject d = f(c);
    if(c == d) 
      System.out.println("c == d");
    else 
      System.out.println("c != d");
    System.out.println("c = " + c);
    System.out.println("d = " + d);
  }
} ///:~
不管怎样,clone()必须能够访问,所以必须将其设为public(公共的)。其次,作为clone()的初期行动,应调用clone()的基础类版本。这里调用的clone()是Object内部预先定义好的。之所以能调用它,是由于它具有protected(受到保护的)属性,所以能在衍生的类里访问。Object.clone()会检查原先的对象有多大,再为新对象腾出足够多的内存,将所有二进制位从原来的对象复制到新对象。这叫作“按位复制”,而且按一般的想法,这个工作应该是由clone()方法来做的。但在Object.clone()正式开始操作前,首先会检查一个类是否Cloneable,即是否具有克隆能力——换言之,它是否实现了Cloneable接口。若未实现,Object.clone()就掷出一个CloneNotSupportedException违例,指出我们不能克隆它。因此,我们最好用一个try-catch块将对super.clone()的调用代码包围(或封装)起来,试图捕获一个应当永不出现的违例(因为这里确实已实现了Cloneable接口)。在LocalCopy中,两个方法g()和f()揭示出两种参数传递方法间的差异。其中,g()演示的是按引用传递,它会修改外部对象,并返回对那个外部对象的一个引用。而f()是对自变量进行克隆,所以将其分离出来,并让原来的对象保持独立。随后,它继续做它希望的事情。甚至能返回指向这个新对象的一个句柄,而且不会对原来的对象产生任何副作用。注意下面这个多少有些古怪的语句:v = (MyObject)v.clone();它的作用正是创建一个本地副本。为避免被这样的一个语句搞混淆,记住这种相当奇怪的编码形式在Java中是完全允许的,因为有一个名字的所有东西实际都是一个句柄。所以句柄v用于克隆一个它所指向的副本,而且最终返回指向基础类型Object的一个句柄(因为它在Object.clone()中是那样被定义的),随后必须将其造型为正确的类型。在main()中,两种不同参数传递方式的区别在于它们分别测试了一个不同的方法。输出结果如下:
a == b
a = 12
b = 12
c != d
c = 47
d = 48
大家要记住这样一个事实:Java对“是否等价”的测试并不对所比较对象的内部进行检查,从而核实它们的值是否相同。==和!=运算符只是简单地对比句柄的内容。若句柄内的地址相同,就认为句柄指向同样的对象,所以认为它们是“等价”的。所以运算符真正检测的是“由于别名问题,句柄是否指向同一个对象?”

凌众科技专业提供服务器租用、服务器托管、企业邮局、虚拟主机等服务,公司网站:http://www.lingzhong.cn 为了给广大客户了解更多的技术信息,本技术文章收集来源于网络,凌众科技尊重文章作者的版权,如果有涉及你的版权有必要删除你的文章,请和我们联系。以上信息与文章正文是不可分割的一部分,如果您要转载本文章,请保留以上信息,谢谢!

分享到: 更多

Copyright ©1999-2011 厦门凌众科技有限公司 厦门优通互联科技开发有限公司 All rights reserved

地址(ADD):厦门软件园二期望海路63号701E(东南融通旁) 邮编(ZIP):361008

电话:0592-5908028 传真:0592-5908039 咨询信箱:web@lingzhong.cn 咨询OICQ:173723134

《中华人民共和国增值电信业务经营许可证》闽B2-20100024  ICP备案:闽ICP备05037997号