浅复制是指复制对象时仅仅复制对象本身(包括对象中的基本变量),而不复制对象包含的引用指向的对象。深复制不仅复制对象本身,而且复制对象包含的引用指向的对象。
复制对象时需要调用Object类的clone方法:
1 protected native Object clone() throws CloneNotSupportedException;
步骤:
1 被复制的类需要实现Clonenable接口(不实现的话在调用clone方法时会抛出CloneNotSupportedException异常) 。而该接口为标记接口(不含任何抽象方法)。
2 重写clone()方法,访问修饰符设为public,通过调用super.clone()方法得到需要的复制对象。
浅复制
1 class Address { 2 private String add; 3 4 public String getAdd() { 5 return add; 6 } 7 8 public void setAdd(String add) { 9 this.add = add; 10 } 11 12 } 13 14 class Student implements Cloneable{ 15 private int number; 16 17 private Address addr; 18 19 public Address getAddr() { 20 return addr; 21 } 22 23 public void setAddr(Address addr) { 24 this.addr = addr; 25 } 26 27 public int getNumber() { 28 return number; 29 } 30 31 public void setNumber(int number) { 32 this.number = number; 33 } 34 35 @Override 36 public Object clone() { 37 Student stu = null; 38 try{ 39 stu = (Student)super.clone(); 40 }catch(CloneNotSupportedException e) { 41 e.printStackTrace(); 42 } 43 return stu; 44 } 45 } 46 public class Test { 47 48 public static void main(String args[]) { 49 50 Address addr = new Address(); 51 addr.setAdd("杭州市"); 52 Student stu1 = new Student(); 53 stu1.setNumber(123); 54 stu1.setAddr(addr); 55 56 Student stu2 = (Student)stu1.clone(); 57 58 System.out.println("学生1:" + stu1.getNumber() + ",地址:" + stu1.getAddr().getAdd()); 59 System.out.println("学生2:" + stu2.getNumber() + ",地址:" + stu2.getAddr().getAdd()); 60 61 addr.setAdd("西湖区"); 62 63 System.out.println("学生1:" + stu1.getNumber() + ",地址:" + stu1.getAddr().getAdd()); 64 System.out.println("学生2:" + stu2.getNumber() + ",地址:" + stu2.getAddr().getAdd()); 65 } 66 }
结果如下:
1 学生1:123,地址:杭州市 2 学生2:123,地址:杭州市 3 学生1:123,地址:杭州市 4 学生2:123,地址:杭州市 5 学生1:123,地址:西湖区 6 学生2:123,地址:西湖区
两个学生的地址都改变了。原因是浅复制只是复制了addr变量的引用,并没有真正地开辟另一块空间来存储地址对象。
深复制
1 class Address implements Cloneable { 2 private String add; 3 4 public String getAdd() { 5 return add; 6 } 7 8 public void setAdd(String add) { 9 this.add = add; 10 } 11 12 @Override 13 public Object clone() { 14 Address addr = null; 15 try{ 16 addr = (Address)super.clone(); 17 }catch(CloneNotSupportedException e) { 18 e.printStackTrace(); 19 } 20 return addr; 21 } 22 } 23 24 class Student implements Cloneable{ 25 private int number; 26 27 private Address addr; 28 29 public Address getAddr() { 30 return addr; 31 } 32 33 public void setAddr(Address addr) { 34 this.addr = addr; 35 } 36 37 public int getNumber() { 38 return number; 39 } 40 41 public void setNumber(int number) { 42 this.number = number; 43 } 44 45 @Override 46 public Object clone() { 47 Student stu = null; 48 try{ 49 stu = (Student)super.clone(); //浅复制 50 }catch(CloneNotSupportedException e) { 51 e.printStackTrace(); 52 } 53 stu.addr = (Address)addr.clone(); //深度复制 54 return stu; 55 } 56 } 57 public class Test { 58 59 public static void main(String args[]) { 60 61 Address addr = new Address(); 62 addr.setAdd("杭州市"); 63 Student stu1 = new Student(); 64 stu1.setNumber(123); 65 stu1.setAddr(addr); 66 67 Student stu2 = (Student)stu1.clone(); 68 69 System.out.println("学生1:" + stu1.getNumber() + ",地址:" + stu1.getAddr().getAdd()); 70 System.out.println("学生2:" + stu2.getNumber() + ",地址:" + stu2.getAddr().getAdd()); 71 72 addr.setAdd("西湖区"); 73 74 System.out.println("学生1:" + stu1.getNumber() + ",地址:" + stu1.getAddr().getAdd()); 75 System.out.println("学生2:" + stu2.getNumber() + ",地址:" + stu2.getAddr().getAdd()); 76 } 77 }
结果如下:
1 学生1:123,地址:杭州市 2 学生2:123,地址:杭州市 3 学生1:123,地址:西湖区 4 学生2:123,地址:杭州市
参考资料