clone方法的使用,深层次拷贝!

解决方案 »

  1.   

    class Student implements Cloneable { //虽然 这个接口中没有任何的方法,但我们要实现这个接口 它是告诉编译器 我们现在这个类它的对象支持克隆了    否则便会出现CloneNotSupportedException 异常{
      int age;
      String name;
      Professor p;
      
      
     Student() {
      age=22;
      name="sss";
      p=new Professor();
      p.name="SunXin";
      p.age=30;
     
    }
     Student(String name,int age) {
      this.age=age;
      this.name=name;
      
      p=new Professor();
      p.name="SunXin";
      p.age=30;
      
    }
     
     Student(String name,int age,Professor p) {
      this.age=age;
      this.name=name;
      this.p=p; 
    }


    public String toString() {    //
    return "The student's name is: "+name+", age is: "+age+"\nThe professor's name is: "+p.name+", age is: "+p.age;
    }



    public Object clone()  //覆盖基类的克隆方法,必须声明为public
    {
       //Object o = null;
         Student o =null;  //    必须必须 要写上=null,否则编译出错
       try                                                 //这里需要捕获异常
           {
            o = (Student)super.clone();      //克隆时是将以上数据一一拷贝 对p拷贝的只是一个引用   //Object的克隆方法会自动识别出你要复制的是那一类对象 然后为此对象分配内存间,并进行对象复制
           }
           catch(Exception e/*CloneNotSupportedException e*/)
            {
            System.out.println("在catch(Exception e)中对 异常 的捕获");
            System.out.println(e);          // 会自动调用 e的  toString 方法                              
            //System.out.println(e.toString);  
            }
            o.p=(Professor)p.clone();
       return o;
    }

    }




    class Professor implements Cloneable{
      int age;
      String name;
      
       Professor() {
      age=0;
      name="unknow";
     }
      Professor(String name,int age) {
      this.age=age;
      this.name=name;
    }


    public Object clone()  //覆盖基类的克隆方法,必须声明为public
    {
       Object o = null;
       try                                                 //这里需要捕获异常
           {
            o = super.clone();      //克隆时是将以上数据一一拷贝 对p拷贝的只是一个引用
           }
           catch(Exception e/*CloneNotSupportedException e*/)
            {
            System.out.println("在catch(Exception e)中对 异常 的捕获");
            System.out.println(e);          // 会自动调用 e的  toString 方法                              
            //System.out.println(e.toString);  
            }
       return o;
    }

    }



    class Test {

      public static void main(String[] args){
        Student stu1 = new Student("sxz",22);
      System.out.println(stu1);
      
      
      Student stu2 =(Student) stu1.clone();  //当拷贝时 没有引用形的变量 叫做 前层次的拷贝
      stu2.name="FenLei"; 
      System.out.println(stu2);
      
      Student stu2_2 = stu2;                                  
      stu2_2.age=23;
      System.out.println(stu2);
      
      
      Professor p = new Professor("Sunxin",35);
      Student stu3 = new Student("Sun Xuezhi",22,p);
      System.out.println(stu3);
      
      
      Student stu3_3 = (Student)stu3.clone(); //克隆时是将以上数据(String name,int age ,Professor p)的一一拷贝  p拷贝是一个引用
      stu3_3.p.age=40;                          //所以会改变p3.p.age的内容  //注意!!!
      System.out.println(stu3);                                             //注意!! 这里String也是一个引用类型 为什么修改他不会影响原来的呢 ? 我们要注意到 一个String 对象是一个常量对象 当我们这么 stu2.name="FenLei";  作时,是产生了"FenLei" 这么一个对象 然后将它的引用赋给了name

      }
    }

      

  2.   


    class Student implements Cloneable { //虽然 这个接口中没有任何的方法,但我们要实现这个接口 它是告诉编译器 我们现在这个类它的对象支持克隆了    否则便会出现CloneNotSupportedException 异常{
      int age;
      String name;
      Professor p;
      
      
     Student() {
      age=22;
      name="sss";
      p=new Professor();
      p.name="SunXin";
      p.age=30;
     
    }
     Student(String name,int age) {
      this.age=age;
      this.name=name;
      
      p=new Professor();
      p.name="SunXin";
      p.age=30;
      
    }
     
     Student(String name,int age,Professor p) {
      this.age=age;
      this.name=name;
      this.p=p; 
    }


    public String toString() {    //
    return "The student's name is: "+name+", age is: "+age+"\nThe professor's name is: "+p.name+", age is: "+p.age;
    }



    public Object clone()  //覆盖基类的克隆方法,必须声明为public
    {
       Object o = null;
       try                                                 //这里需要捕获异常
           {
            o = super.clone();      //克隆时是将以上数据一一拷贝 对p拷贝的只是一个引用
           }
           catch(Exception e/*CloneNotSupportedException e*/)
            {
            System.out.println("在catch(Exception e)中对 异常 的捕获");
            System.out.println(e);          // 会自动调用 e的  toString 方法                              
            //System.out.println(e.toString);  
            }
       return o;
    }

    }




    class Professor {
      int age;
      String name;
      
       Professor() {
      age=0;
      name="unknow";
     }
      Professor(String name,int age) {
      this.age=age;
      this.name=name;
    }

    }



    class Test {

      public static void main(String[] args){
        Student stu1 = new Student("sxz",22);
      System.out.println(stu1);
      
      
      Student stu2 = (Student)stu1.clone();  //当拷贝时 没有引用形的变量 叫做 前层次的拷贝
      stu2.name="FenLei"; 
      System.out.println(stu2);
      
      Student stu2_2 = stu2;                                  
      stu2_2.age=23;
      System.out.println(stu2);
      
      
      Professor p = new Professor("Sunxin",35);
      Student stu3 = new Student("Sun Xuezhi",22,p);
      System.out.println(stu3);
      
      
      Student stu3_3 =(Student) stu3.clone(); //克隆时是将以上数据(String name,int age ,Professor p)的一一拷贝  p拷贝是一个引用
      stu3_3.p.age=40;                          //所以会改变p3.p.age的内容  //注意!!!
      System.out.println(stu3);                                             //注意!! 这里String也是一个引用类型 为什么修改他不会影响原来的呢 ? 我们要注意到 一个String 对象是一个常量对象 当我们这么 stu2.name="FenLei";  作时,是产生了"FenLei" 这么一个对象 然后将它的引用赋给了name

      }
    }