public class Test
{
static class Strings implements Cloneable
{
private String str;
public void SetStr(String s){
this.str = s;
}
public String GetStr(){
return this.str;
}
protected Object clone()throws CloneNotSupportedException{
return super.clone(); }
} public static void main(String[] args)
{
Strings str1 = new Strings();
str1.SetStr("Hello World!"); System.out.println("-----------------");
System.out.println("str1.SetStr(\"Hello World!\");");
System.out.println("str2 = (Strings)str1.clone();");
Strings str2 = null;
try {
str2 = (Strings)str1.clone();
} catch (CloneNotSupportedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
System.out.println("str1:"+str1.GetStr());
System.out.println("str2:"+str2.GetStr());
System.out.print("print object str1:");
System.out.println(str1);
System.out.print("print object str2:");
System.out.println(str2); System.out.println("-----------------"); System.out.println("str2.setStr(\"Hello!\");");
str2.SetStr("Hello!");
System.out.println("str1:"+str1.GetStr());
System.out.println("str2:"+str2.GetStr());
System.out.print("print object str1:");
System.out.println(str1);
System.out.print("print object str2:");
System.out.println(str2);
System.out.println("-----------------"); System.out.println("str1 = str2;");
str1 = str2;
str2.SetStr("Hello-------changed!");
System.out.println("str1:"+str1.GetStr());
System.out.println("str2:"+str2.GetStr());
System.out.print("print object str1:");
System.out.println(str1.hashCode());
System.out.println(str1);
System.out.print("print object str2:");
System.out.println(str2.hashCode());
System.out.println(str2); System.out.println("-----------------");
}
}如上code。
问题:1.为何用super.clone?
我的理解:调用super.clone,则调用Test的基类来复制,那复制的不就变成了Test的基类?
如果我还有另外一个Test2,他和Test来自同一个基类。那调用super.clone,java怎么区分,或者正确复制Test,Test2.
2.网上看到很多人都说override的时候要将clone的属性从protected改为public。
但是我没改动也是可以的,就是如上代码也是可以正常运行。
那么,为什么那么多人说要改为public,这里有什么巧妙之处,被我看肤浅了。先谢谢了
{
static class Strings implements Cloneable
{
private String str;
public void SetStr(String s){
this.str = s;
}
public String GetStr(){
return this.str;
}
protected Object clone()throws CloneNotSupportedException{
return super.clone(); }
} public static void main(String[] args)
{
Strings str1 = new Strings();
str1.SetStr("Hello World!"); System.out.println("-----------------");
System.out.println("str1.SetStr(\"Hello World!\");");
System.out.println("str2 = (Strings)str1.clone();");
Strings str2 = null;
try {
str2 = (Strings)str1.clone();
} catch (CloneNotSupportedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
System.out.println("str1:"+str1.GetStr());
System.out.println("str2:"+str2.GetStr());
System.out.print("print object str1:");
System.out.println(str1);
System.out.print("print object str2:");
System.out.println(str2); System.out.println("-----------------"); System.out.println("str2.setStr(\"Hello!\");");
str2.SetStr("Hello!");
System.out.println("str1:"+str1.GetStr());
System.out.println("str2:"+str2.GetStr());
System.out.print("print object str1:");
System.out.println(str1);
System.out.print("print object str2:");
System.out.println(str2);
System.out.println("-----------------"); System.out.println("str1 = str2;");
str1 = str2;
str2.SetStr("Hello-------changed!");
System.out.println("str1:"+str1.GetStr());
System.out.println("str2:"+str2.GetStr());
System.out.print("print object str1:");
System.out.println(str1.hashCode());
System.out.println(str1);
System.out.print("print object str2:");
System.out.println(str2.hashCode());
System.out.println(str2); System.out.println("-----------------");
}
}如上code。
问题:1.为何用super.clone?
我的理解:调用super.clone,则调用Test的基类来复制,那复制的不就变成了Test的基类?
如果我还有另外一个Test2,他和Test来自同一个基类。那调用super.clone,java怎么区分,或者正确复制Test,Test2.
2.网上看到很多人都说override的时候要将clone的属性从protected改为public。
但是我没改动也是可以的,就是如上代码也是可以正常运行。
那么,为什么那么多人说要改为public,这里有什么巧妙之处,被我看肤浅了。先谢谢了
谢谢,但是我还是想不通,clone()这个函数到底复制的哪个对象:(假设为如上code)
(1)复制Strings类。
(2)?。
如果为(1),有两个问题:(a)那么super.clone(),不就表示复制Strings的基类。
(b)如果我还有另外一个类Strings1,它的基类与Strings的基类相同。
java虽然知道是在两个不同的子类里面,但是调用super.clone()后,这两个类的super.clone(),应该一样。
这样子复制出来的只会是一个结果,就是错的了,因为我要复制strings,strings1。
如果是(2),(2)是?
还有一种可能是这里的super.clone(),并不能从字面那么来理解(父类的函数),它只是一个表述方式。
好吧,那如何理解这个super.clone()?
(1)复制Strings类。
(2)?。
如果为(1),有两个问题:(a)那么super.clone(),不就表示复制Strings的基类。
(b)如果我还有另外一个类Strings1,它的基类与Strings的基类相同。
java虽然知道是在两个不同的子类里面,但是调用super.clone()后,这两个类的super.clone(),应该一样。
这样子复制出来的只会是一个结果,就是错的了,因为我要复制strings,strings1。
如果是(2),(2)是?
还有一种可能是这里的super.clone(),并不能从字面那么来理解(父类的函数),它只是一个表述方式。
好吧,那如何理解这个super.clone()?
答:
1)clone()复制的是Strings类的对象
1)中的(a):那么super.clone(),不就表示复制Strings的基类?错.
super.clone()的操作是:(还是以Object中的clone()来说明吧)
<1>检查当前对象this所属的类(指:你的Strings类有没有实现Cloneable接口,若没有则抛出:CloneNotSupportedException
<2>创建当前对象this所属的类(即你的Strings类)的一个对象(称为:copy_object),并对该copy_object进行初始化,使得copy_object的数据成员值与当前对象this中数据成员值一模一样(即:当前对象this的二进制拷贝)--这就是所谓的"浅复制". 对于你的代码,即:copy_object对象中的数据成员private String str; 与被复制的当前对象this中的private String str 引用的是同一个字符串对象.由于:字符串对象是内部值不可改变的常对象,因而:对于浅复制,这是没有问题的.使用效果与"深复制"相同. 同样:基本数据类型的数据成员,"浅复制"与"深复制"使用效果也相同.1)中的(b):根据(a),从而(b)中的问题自然不存在了.3)在子类重写clone()时,都将protected改为public,这是为了方便别人使用.
如果你的类里边的域都是基本类型或者不可变类型的话,你只需在你的clone方法中super.clone()即可