搜尋

首頁  >  問答  >  主體

關於java深拷貝的疑問

下面這段程式碼中,為什麼

//对引用的对象也进行复制
o.p=(Professor)p.clone(); 

就能夠實現深拷貝呢?

class Professor implements Cloneable 
{ 
  String name; 
  int age; 
  Professor(String name,int age) 
  { 
  this.name=name; 
  this.age=age; 
  } 
 public Object clone() 
  { 
   Object o=null; 
  try 
   { 
    o=super.clone(); 
   } 
  catch(CloneNotSupportedException e) 
   { 
    System.out.println(e.toString()); 
   } 
  return o; 
  } 
} 
public class Student implements Cloneable 
{ 
  String name; 
  int age; 
  Professor p; 
  Student(String name,int age,Professor p) 
  { 
  this.name=name; 
  this.age=age; 
  this.p=p; 
  } 
 public Object clone() 
  { 
   Student o=null; 
  try 
   { 
    o=(Student)super.clone(); 
   } 
  catch(CloneNotSupportedException e) 
   { 
    System.out.println(e.toString()); 
   } 
   //对引用的对象也进行复制
   o.p=(Professor)p.clone(); 
  return o; 
  }  
 public static void main(String[] args) 
  { 
  Professor p=new Professor("wangwu",50); 
  Student s1=new Student("zhangsan",18,p); 
  Student s2=(Student)s1.clone(); 
  s2.p.name="lisi"; 
  s2.p.age=30; 
  //学生1的教授不 改变。
  System.out.println("name="+s1.p.name+","+"age="+s1.p.age); 
  System.out.println("name="+s2.p.name+","+"age="+s2.p.age); 
 } 
} 
ringa_leeringa_lee2787 天前522

全部回覆(4)我來回復

  • 巴扎黑

    巴扎黑2017-05-17 10:09:33

    這只是表面上看起來是「深拷貝」, 實際上Student、Professor都沒有實現深拷貝。

    你在main方法增加幾個輸出:

    Professor p=new Professor("wangwu",50);
            Student s1=new Student("zhangsan",18,p);
            Student s2=(Student)s1.clone();
    
            System.out.println(s1.p == s2.p); //false
    
            System.out.println(s1.name == s2.name); // true
    
            System.out.println(s1.p.name == s2.p.name); //true
    
            s2.p.name="lisi";
            s2.p.age=30;
            //学生1的教授不 改变。
            System.out.println("name="+s1.p.name+","+"age="+s1.p.age);
            System.out.println("name="+s2.p.name+","+"age="+s2.p.age);
    
            System.out.println(s1.name == s2.name); //true
    
            System.out.println(s1.p.name == s2.p.name); //false

    即可看到,s1,s2的name仍然是"==", 在未set p.name時其name也為"==", 所以說都沒有實現深拷貝。
    當你set s2.p.name時,s2.p.name指向了另一個字串常數的位址,所以(s1.p.name == s2.p.name); //false

    回覆
    0
  • 淡淡烟草味

    淡淡烟草味2017-05-17 10:09:33

    你這個是淺複製,只能複製基本的資料類型,要複製物件成員變量,還需要呼叫該成員變數的clone方法,我是這麼理解的,多次淺複製實現深複製

    回覆
    0
  • 天蓬老师

    天蓬老师2017-05-17 10:09:33

    並不是深拷貝, 你可以試試clone得到的professor.name与原来的professor.name==的, 說明String還是引用的原來的

    回覆
    0
  • 淡淡烟草味

    淡淡烟草味2017-05-17 10:09:33

    jdk clone方法的預設實作都是value copy,對於基本型,就是把copy值。對於引用,就是copy引用所指向的位址。

    所以如果沒有o.p=(Professor)p.clone();這段程式碼,那麼原對象和clone對象的p,引用的都是同一個Professor對象,也就是淺copy。

    回覆
    0
  • 取消回覆