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,这里有什么巧妙之处,被我看肤浅了。先谢谢了

解决方案 »

  1.   

    不好意思,写错了:Test为Strings
      

  2.   

    这些都都继承至Object 类,调用super.clone()方法,确保克隆的正确性,这只是一个浅克隆至于把protected 改为public 是为了子类的对象方便调用clone()方法。如果你不设为public ,在其它类里边如何能调用其clone方法呢
      

  3.   


    谢谢,但是我还是想不通,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()?
                                      
                                      
      

  4.   

    问:但是我还是想不通,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)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,这是为了方便别人使用.
      

  5.   

    super只是调用父类的方法,跟父类的instance没有关系
      

  6.   

    object中的clone()方法已经为你做好了,不过它实现的是浅拷贝,只是拷贝当前对象的各个域(二进制值)
    如果你的类里边的域都是基本类型或者不可变类型的话,你只需在你的clone方法中super.clone()即可