Java对象克隆问题
2015-10-12 14:21
246 查看
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++不可以,
因为无法在写拷贝构造函数时调用本身。**
相关文章推荐
- java对世界各个时区(TimeZone)的通用转换处理方法(转载)
- java-注解annotation
- java-模拟tomcat服务器
- java-用HttpURLConnection发送Http请求.
- java-WEB中的监听器Lisener
- Android IPC进程间通讯机制
- Android Native 绘图方法
- Android java 与 javascript互访(相互调用)的方法例子
- 介绍一款信息管理系统的开源框架---jeecg
- 聚类算法之kmeans算法java版本
- java实现 PageRank算法
- PropertyChangeListener简单理解
- 插入排序
- 冒泡排序
- 堆排序
- 快速排序
- 二叉查找树
- [原创]java局域网聊天系统