Java中的拷贝方式分为深拷贝和浅拷贝。简单来讲,深拷贝就是把一个对象中的全部值,若是被拷贝对象中有对其余对象的引用,那么这个引用指向的对象自己会被从新建立。浅拷贝和深拷贝相似,可是若是被拷贝对象中有对其余对象的引用,只是这个引用会被拷贝,而不是这个被引用的对象。 html
http://bbs.itheima.com/thread-23776-1-1.html?fstgj java
之前的学习网站,-全套java视频教程,须要的本身看下,能够去这个网站下载,下载视频免费,不须要注册和作什么任务 学习
提及来有点绕口,那么咱们就看看下面的图解吧: 网站
深拷贝: this
浅拷贝: spa
来看下面这段代码: code
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()就好了。 htm
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; } |