java中的clone机制
来源:互联网 发布:福州市各县区经济数据 编辑:程序博客网 时间:2024/05/16 06:55
为什么要使用clone?
在实际编程过程中,我们常常要遇到这种情况:有一个对象A,在某一时刻A中已经包含了一些有效值,此时可能会需要一个和A完全相同新对象B,并且此后对B任何改动都不会影响到A中的值,也就是说,A与B是两个独立的对象,但B的初始值是由A对象确定的。在这种情况下常常使用clone,但解决上述问题方法很多,如先new一个类,然后把原始对象中的信息赋到新对象中,那为什么需要clone呢?
(1)实现clone方法简单、方便
(2)Object类的clone()一个native方法,native方法的效率一般来说都是远高于java中的非native方法,因此clone方法是高效的
影子clone与深度clone
由于java中 ,对非基本类型变量,它们保存的仅仅是对象的引用,所以使用上要特别小心。请看以下一组代码
private String name;
private int number;
public void setName(String arg) ...{
name = arg;
}
public String getName() ...{
return name;
}
public Object clone() throws CloneNotSupportedException ...{
return super.clone();
}
}
public class Sheepfold implements Cloneable ...{
public Sheep sheep;
public String name;
public int number;
public Sheepfold() ...{
sheep = new Sheep();
}
public Object clone() throws CloneNotSupportedException ...{
return super.clone();
}
}
public class Main ...{
public static void main(String[] args) throws Exception ...{
Sheepfold fold = new Sheepfold();
fold.name = "小羊圈";
fold.number=10;
fold.sheep.setName("小羊");
Sheepfold fold2 = (Sheepfold)fold.clone();
System.out.println(" fold2.name = " + fold2.name);
System.out.println(" fold2.number = " + fold2.number);
System.out.println(" fold2.sheep.getName() = " + fold2.sheep.getName());
fold2.name = "大羊圈";
fold2.sheep.setName("大羊");
fold2.number=100;
System.out.println("=====================================");
System.out.println(" fold2.name = " + fold2.name);
System.out.println(" fold2.number = " + fold2.number);
System.out.println("* fold2.sheep.getName() = " + fold2.sheep.getName());
System.out.println(" fold.name = " + fold.name);
System.out.println(" fold.number = " + fold.number);
System.out.println("* fold.sheep.getName() = " + fold.sheep.getName());
System.out.println("=====================================");
}
}
输出结果
fold2.name = 小羊圈
flod2.number = 10
fold2.sheep.getName() = 小羊
=====================================
fold2.name = 大羊圈
flod2.number = 100
* fold2.sheep.getName() = 大羊
fold.name = 小羊圈
flod2.number = 10
* fold.sheep.getName() = 大羊
=====================================
在此之前,我们只对fold2.sheep的name赋过值。为什么fold.sheep的name也变为了“大羊”呢?原因很简单,因为它们是指向同一个对象的不同引用。从中可以看出,调用Object类中clone()方法时,首先在内存中划分一块同原对象相同的空间,然后将原对象的内容原样拷贝至新对象。我们知道,java中有基本数据类型,对于基本数据类型,这样的操作是没有问题的,但对非基本类型变量,它们保存的仅仅是对象的引用,这也是为什么clone后非基本类型变量和原对象中的变量指向同一个对象的原因。可能你已经注意到,程序中用到了String类型,即对象,为什么没有出现引用指向同一地址的情况?这是因为String是一个不可更改的类(immutable class),每次给它赋值时,都会产生一个新的String对象。如String str = "a"; str += "b";在这两句代码中,当执行str += "b"时,实际上是重新成生了一个值为“ab”的String对象,即重新分配了一块内存空间。以上clone方法通常被称为“影子clone”。“影子clone”给我们留下了一个问题,即多个引用指向同一个对象。如何解决该问题呢?答案为“深度clone”。把上面的例子改成深度clone很简单,只需将Sheepfold的clone()方法改为如下即可:
public Object clone() throws CloneNotSupportedException {
Sheepfold fold = (Sheepfold)super.clone();
sheep = (Sheep)fold.sheep.clone();
return fold;
}
- java中的clone机制
- java中的clone机制
- java中的clone机制
- Java中的克隆(Clone)机制
- Java中的克隆(Clone)机制
- Java中的克隆(Clone)机制
- Java中的克隆(Clone)机制
- Java中的克隆(Clone)机制
- Java中的克隆(Clone)机制
- Java中的克隆(Clone)机制
- Java Clone机制[转]
- Java的clone机制
- Java Clone机制
- Java clone机制
- JAVA Clone机制
- java clone()机制
- Java Clone机制
- java 中的 clone()
- 作用域scope概念
- 光学镜头概述及分类[机器视觉系列]
- asp中session具体是什么
- 利用Java Beans在应用程序中创建组件
- reflection demo(inclue source code)
- java中的clone机制
- Java虚拟机
- java经典问题:传值还是传引用
- js 几种常用的表单输入判断
- 用于 Java 程序(J2SE, JSP/Servlet) 的可直接返回连接以及定时关闭超时连接的连接池程序
- JSP数据库连接方式总结
- 编译与解释
- 600127:金健米业分析
- 可敬可悲硅谷人 科技富豪失乐园