clone()方法深拷贝与浅拷贝

x33g5p2x  于2022-01-04 转载在 其他  
字(2.0k)|赞(0)|评价(0)|浏览(387)

JAVA中除了8种基本类型传参数是值传递外,其他的类对象传参数都是引用,如果直接使用clone()方法,只能完成对象的浅拷贝,若想实现深拷贝,则要重写clone()方法。

一,浅拷贝

  1. class Employee implements Cloneable{
  2. private int age ;
  3. private String name;
  4. private Date date;
  5. public Employee(int age, String name, Date date) {
  6. this.name = name;
  7. this.age = age;
  8. this.date = date;
  9. }
  10. public int getAge() {
  11. return age;
  12. }
  13. public String getName() {
  14. return name;
  15. }
  16. public Date getDate() {
  17. return date;
  18. }
  19. @Override
  20. protected Object clone() throws CloneNotSupportedException {
  21. return super.clone();
  22. }
  23. }

类 Employee 有三个属性,其中只有 age 是基本类型。clone() 方法是调用了父类的实现,并未重写。验证一下现在的 clone() 方法是否为浅拷贝。(注意:要使用 clone() 方法就必须实现 Cloneable 标记接口)

  1. public class Test {
  2. public static void main(String[] args) throws CloneNotSupportedException {
  3. Employee e1 = new Employee(15,"小明",new Date());
  4. Employee e2 = (Employee) e1.clone();
  5. System.out.println(e1==e2);
  6. System.out.println(e1.getAge()==e2.getAge());
  7. System.out.println(e1.getName()==e2.getName());
  8. System.out.println(e1.getDate()==e2.getDate());
  9. }
  10. }

结果:

解释:
1,因为使用 clone() 方式时会给新的对象分配一个新的内存,而“==”在比较引用类型对象时看的是两个变量指向的对象在内存中存储的地址是否相等,所以结果为 false。

2,对基本数据类型(如int,double),使用“==”比较的是两个变量存储的值是否相等而非两个变量是否指向同一内存地址,所以结果为true。

3,String 和 Date 都是引用数据类型,对于这种数据类型,使用“==”时比较的是两个变量是否指向同一内存地址,结果为 true,说明对象 e2 的 name 属性和对象 e1 的 name 属性指向同一个内存地址,一个变化了另一个也会随之变化,date 属性也是同样的情况。这就是浅拷贝,如图:

二,深拷贝

实现深拷贝需要重写 clone() 方法:

  1. class Employee implements Cloneable{
  2. private int age ;
  3. private String name;
  4. private Date date;
  5. public Employee(int age, String name, Date date) {
  6. this.name = name;
  7. this.age = age;
  8. this.date = date;
  9. }
  10. public int getAge() {
  11. return age;
  12. }
  13. public String getName() {
  14. return name;
  15. }
  16. public Date getDate() {
  17. return date;
  18. }
  19. @Override
  20. protected Object clone() throws CloneNotSupportedException {
  21. Employee cloned = (Employee) super.clone();
  22. cloned.name = new String(name);
  23. cloned.date = (Date) date.clone();
  24. return cloned;
  25. }
  26. }

验证是否为深拷贝:

  1. public class Test {
  2. public static void main(String[] args) throws CloneNotSupportedException {
  3. Employee e1 = new Employee(15,"小明",new Date());
  4. Employee e2 = (Employee) e1.clone();
  5. System.out.println(e1==e2);
  6. System.out.println(e1.getAge()==e2.getAge());
  7. System.out.println(e1.getName()==e2.getName());
  8. System.out.println(e1.getDate()==e2.getDate());
  9. }
  10. }

结果:

相关文章