Java对象克隆问题

来源:互联网 发布:dhcp绑定mac地址失败 编辑:程序博客网 时间:2024/06/04 19:11

Object中 clone方法的源代码

/**创建并返回此对象的一个副本。“副本”的准确含义可能依赖于对象的类。这样做的目的是,对于任何对象 x,表达式:x.clone() != x为 true,表达式:x.clone().getClass() == x.getClass()也为 true,但这些并非必须要满足的要求。一般情况下:x.clone().equals(x)为 true,但这并非必须要满足的要求。按照惯例,返回的对象应该通过调用 super.clone 获得。如果一个类及其所有的超类(Object 除外)都遵守此约定,则 x.clone().getClass() == x.getClass()。按照惯例,此方法返回的对象应该独立于该对象(正被复制的对象)。要获得此独立性,在 super.clone 返回对象之前,有必要对该对象的一个或多个字段进行修改。这通常意味着要复制包含正在被复制对象的内部“深层结构”的所有可变对象,并使用对副本的引用替换对这些对象的引用。如果一个类只包含基本字段或对不变对象的引用,那么通常不需要修改 super.clone 返回的对象中的字段。Object 类的 clone 方法执行特定的复制操作。首先,如果此对象的类不能实现接口 Cloneable,则会抛出 CloneNotSupportedException。注意,所有的数组都被视为实现接口 Cloneable。否则,此方法会创建此对象的类的一个新实例,并像通过分配那样,严格使用此对象相应字段的内容初始化该对象的所有字段;这些字段的内容没有被自我复制。所以,此方法执行的是该对象的“浅表复制”,而不“深层复制”操作。Object 类本身不实现接口 Cloneable,所以在类为 Object 的对象上调用 clone 方法将会导致在运行时抛出异常。返回:此实例的一个副本。抛出:CloneNotSupportedException - 如果对象的类不支持 Cloneable 接口,则重写 clone 方法的子类也会抛出此异常,以指示无法复制某个实例。*/protected native Object clone() throws CloneNotSupportedException;

说明

我们知道,Java中出来常规的字符串、数组等对象所有的都是通过new创建的。
ObjectTest obj; // 只是声明了一个变量(更像C++中的指针),该变量没有指向对象空间。

ObjectA a = new ObjectA();ObjectA b = a;    // a b指向同一个对象空间b = a.clone();    // b指向一个新的对象空间,该对象是由a指向(引用)的空间克隆而来。

实现深拷贝方法

/** * @see Cloneable 接口是一个空接口, 在需要覆盖 Object中 clone()方法时候做一个“标记(表示该类要使用clone()方法)”。 * 因为Java设计人员对clone()方法的使用意见不一。 * 在默认的“机制中”,直接在类设计中调用super.clone()方法(可能与本地方法和虚拟机有关)会生成当前类的一个拷贝对象(浅拷贝模式), * “当前类实例域”中的任用变量成员以浅拷贝的方式指向同一块空间,我们必须重新分配。 * @author yang * */public class Test implements Cloneable{    Object object;    @Override    public Object clone() throws CloneNotSupportedException {        Test t = (Test) super.clone();    // 生成一个当前对象的浅拷贝对象        t.object = new Object();        return t;    }}

Java中没有所谓的C++中的赋值拷贝构造函数

CTest test(3);CTest assignCopy(test); // C++中默认情况下面是浅拷贝(实例域对象指针地址值一样)CTest(const CTest &test) // 要想深拷贝,必须覆盖拷贝构造函数。//WString::WString(const WString &s)//{//    size=s.size;//    str=new char[size+1];//    if(str==null)//        error("WString:overflow");//    strcpy(str,s.str);//}

**Java中可以通过在覆盖克隆函数时候,调用super.clone()方法生成当前类的浅拷贝对象,然后再对对象中的引用型实例域进行分配新对象空间, 但是C++不可以,
因为无法在写拷贝构造函数时调用本身。**

0 0
原创粉丝点击