12.2.2 克隆对象
若需修改一个对象,同时不想改变调用者的对象,就要制作该对象的一个本地副本。这也是本地副本最常见的一种用途。若决定制作一个本地副本,只需简单地使用clone()方法即可。Clone是“克隆”的意思,即制作完全一模一样的副本。这个方法在基础类Object中定义成“protected”(受保护)模式。但在希望克隆的任何衍生类中,必须将其覆盖为“public”模式。例如,标准库类Vector覆盖了clone(),所以能为Vector调用clone(),如下所示://: Cloning.java
// The clone() operation works for only a few
// items in the standard Java library.
import java.util.*;class Int {
private int i;
public Int(int ii) { i = ii; }
public void increment() { i++; }
public String toString() {
return Integer.toString(i);
}
}public class Cloning {
public static void main(String[] args) {
Vector v = new Vector();
for(int i = 0; i < 10; i++ )
v.addElement(new Int(i));
System.out.println("v: " + v);
Vector v2 = (Vector)v.clone();
// Increment all v2's elements:
for(Enumeration e = v2.elements();
e.hasMoreElements(); )
((Int)e.nextElement()).increment();
// See if it changed v's elements:
System.out.println("v: " + v);
}
} ///:~clone()方法产生了一个Object,后者必须立即重新造型为正确类型。这个例子指出Vector的clone()方法不能自动尝试克隆Vector内包含的每个对象——由于别名问题,老的Vector和克隆的Vector都包含了相同的对象。我们通常把这种情况叫作“简单复制”或者“浅层复制”,因为它只复制了一个对象的“表面”部分。实际对象除包含这个“表面”以外,还包括句柄指向的所有对象,以及那些对象又指向的其他所有对象,由此类推。这便是“对象网”或“对象关系网”的由来。若能复制下所有这张网,便叫作“全面复制”或者“深层复制”。
在输出中可看到浅层复制的结果,注意对v2采取的行动也会影响到v:v: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
v: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]一般来说,由于不敢保证Vector里包含的对象是“可以克隆”(注释②)的,所以最好不要试图克隆那些对象。②:“可以克隆”用英语讲是cloneable,请留意Java库中专门保留了这样的一个关键字。
若需修改一个对象,同时不想改变调用者的对象,就要制作该对象的一个本地副本。这也是本地副本最常见的一种用途。若决定制作一个本地副本,只需简单地使用clone()方法即可。Clone是“克隆”的意思,即制作完全一模一样的副本。这个方法在基础类Object中定义成“protected”(受保护)模式。但在希望克隆的任何衍生类中,必须将其覆盖为“public”模式。例如,标准库类Vector覆盖了clone(),所以能为Vector调用clone(),如下所示://: Cloning.java
// The clone() operation works for only a few
// items in the standard Java library.
import java.util.*;class Int {
private int i;
public Int(int ii) { i = ii; }
public void increment() { i++; }
public String toString() {
return Integer.toString(i);
}
}public class Cloning {
public static void main(String[] args) {
Vector v = new Vector();
for(int i = 0; i < 10; i++ )
v.addElement(new Int(i));
System.out.println("v: " + v);
Vector v2 = (Vector)v.clone();
// Increment all v2's elements:
for(Enumeration e = v2.elements();
e.hasMoreElements(); )
((Int)e.nextElement()).increment();
// See if it changed v's elements:
System.out.println("v: " + v);
}
} ///:~clone()方法产生了一个Object,后者必须立即重新造型为正确类型。这个例子指出Vector的clone()方法不能自动尝试克隆Vector内包含的每个对象——由于别名问题,老的Vector和克隆的Vector都包含了相同的对象。我们通常把这种情况叫作“简单复制”或者“浅层复制”,因为它只复制了一个对象的“表面”部分。实际对象除包含这个“表面”以外,还包括句柄指向的所有对象,以及那些对象又指向的其他所有对象,由此类推。这便是“对象网”或“对象关系网”的由来。若能复制下所有这张网,便叫作“全面复制”或者“深层复制”。
在输出中可看到浅层复制的结果,注意对v2采取的行动也会影响到v:v: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
v: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]一般来说,由于不敢保证Vector里包含的对象是“可以克隆”(注释②)的,所以最好不要试图克隆那些对象。②:“可以克隆”用英语讲是cloneable,请留意Java库中专门保留了这样的一个关键字。
解决方案 »
- java进行串口通信,这样操作正确么?
- 在Eclipse中使用Ant的时候,怎么设置系统环境变量
- 怎么实现拖动工具栏的可绘制图标后在鼠标光标下面出现的图像?不好意思分用完了
- [闭月羞花猫] C++ OR JAVA ? 对前两天写的一个小建议的一点点补充
- 怎么样把一个文件保存到数据然后在网页上显示出来 比如word 谢谢
- 请教javac命令当中-d选项和-classpath选项的区别?
- 哪有“java类库大全” 中文说明 和 “jdk1.3.1” 的中文文档?
- 请问如何在Java中调用一个VB所写的DLL?如何调用这个Dll的方法?如何取得和设置这个Dll的属性值?谢谢!
- 在构造jtable时,怎样向它传递数组或变量值!!!
- 在class 中定义的函数内为什么不能使用System.out.println("abc");
- 这样的程序应该怎么编译???
- 谁有JAVA的命名规范?
"若需修改一个对象,同时不想改变调用者的对象,就要制作该对象的一个本地副本。这也是本地副本最常见的一种用途"
能不能具体解释一下!
谢谢!
现在我讲一下,我遇到过的问题,
我用一临时变量来保存数据,再一个循环里不断获得数据并给该临时变量赋值,然后再插入同一个Vector变量中。
最后我从Vector中取数据时发现,tmd都是一样的,而且都是最后传进去的数据。
因为Vector存放的其实是地址,当临时变量值不断被修改,指向所以Vector存放的东东对应的值也就一样被改了。
其实只要在插入Vector时是把临时变量克隆一下,问题就解决了。
当然还要看你的临时变量的object类型是否可以克隆!