Java中对象的浅拷贝与深拷贝

て烟熏妆下的殇ゞ 提交于 2019-12-13 16:55:27

【推荐】2019 Java 开发者跳槽指南.pdf(吐血整理) >>>

Java中的拷贝方式分为深拷贝和浅拷贝。简单来说,深拷贝就是把一个对象中的所有值,如果被拷贝对象中有对其他对象的引用,那么这个引用指向的对象本身会被重新创建。浅拷贝和深拷贝类似,但是如果被拷贝对象中有对其他对象的引用,只是这个引用会被拷贝,而不是这个被引用的对象。

http://bbs.itheima.com/thread-23776-1-1.html?fstgj

以前的学习网站,-全套java视频教程,需要的自己看下,可以去这个网站下载,下载视频免费,不需要注册和做什么任务

说起来有点绕口,那么我们就看看下面的图解吧:

深拷贝: 

浅拷贝: 

来看下面这段代码:

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
public class Car {  private String brand;  private int price;  public String getBrand() {  return brand;  }  public void setBrand(String brand) {  this.brand = brand;  }  public int getPrice() {  return price;  }  public void setPrice(int price) {  this.price = price;  } } 
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
public class Person {  private String name;  private Car car;  public String getName() {  return name;  }  public void setName(String name) {  this.name = name;  }  public Car getCar() {  return car;  }  public void setCar(Car car) {  this.car = car;  } } 
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24
public class test {  public static void main(String[] args) {  Car car1 = new Car();  car1.setBrand("BMW");  car1.setPrice(10000);  Person person1 = new Person();  person1.setCar(car1);  person1.setName("person1");  Person person2 = person1;  person2.setName("person2");  System.out.println(person1.getName()); // person2  System.out.println(person2.getName()); // person2  Car car2 = new Car();  car2.setBrand("Benz");  car2.setPrice(20000);  person1.setCar(car2);  System.out.println(person2.getCar().getBrand()); // Benz  System.out.println(person2.getCar().getPrice()); // 20000  } } 

重点在Person person2 = person1;这一句上,person1里面包括了一个对Car对象的引用,那么这句话是深拷贝还是浅拷贝呢?答案是什么都不是。它只是一个简单的引用传递,执行完这句话以后,person1和person2都指向了同一个person对象,所以无论谁去改变对象,另一个引用再去调用该对象的值都会发生改变。 好吧,言归正传,下面来实现一个浅拷贝。

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31
public class Person implements Cloneable{  private String name;  private Car car;  public String getName() {  return name;  }  public void setName(String name) {  this.name = name;  }  public Car getCar() {  return car;  }  public void setCar(Car car) {  this.car = car;  }  public Object clone() {  Person person = null;  try {  person = (Person) super.clone();  } catch (CloneNotSupportedException e) {  e.printStackTrace();  }  return person;  } } 

 

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
public class CloneTest {  public static void main(String[] args) {  Car car1 = new Car();  car1.setBrand("BMW");  car1.setPrice(10000);  Person originalPerson = new Person();  originalPerson.setCar(car1);  originalPerson.setName("originalPerson");  Person clonePerson = (Person) originalPerson.clone();  originalPerson.setName("originalPerson_1");  originalPerson.getCar().setBrand("Benz");  System.out.println(originalPerson.getName()); // originalPerson_1  System.out.println(originalPerson.getCar().getBrand()); // Benz  System.out.println(clonePerson.getName()); // originalPerson  System.out.println(clonePerson.getCar().getBrand()); // Benz  } } 

Car类不变,Person实现了Cloneable接口,然后重载了父类的clone方法,并且直接调用super.clone()方法来拷贝。但是值得注意的是,父类的clone只是浅拷贝,所以才会有上述的输出结果。那么,要想达到深拷贝,需要做些什么呢? 其实答案已经很明显了,因为clone是浅拷贝,而Car中都是原始类型的变量,所以我们只需要让Car类也实现Cloneable接口,然后重载clone方法,然后回到Person类中,在clone的时候,加上car = car.clone()就行了。

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32
package problems; public class Car implements Cloneable {  private String brand;  private int price;  public String getBrand() {  return brand;  }  public void setBrand(String brand) {  this.brand = brand;  }  public int getPrice() {  return price;  }  public void setPrice(int price) {  this.price = price;  }  public Object clone() {  Car car = null;  try {  car = (Car) super.clone();  } catch (CloneNotSupportedException e) {  e.printStackTrace();  }  return car;  } } 

Person类中的clone:

1 2 3 4 5 6 7 8 9 10
public Object clone() {  Person person = null;  try {  person = (Person) super.clone();  car = (Car) car.clone();  } catch (CloneNotSupportedException e) {  e.printStackTrace();  }  return person; } 
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!