深拷贝和浅拷贝就是指对象的拷贝,一个对象中存在两种类型的属性,一种是基本数据类型,一种是实例对象的引用。
1.浅拷贝是指,对基本数据类型进行值传递,对引用数据类型进行引用传递般的拷贝。
2.深拷贝是指,对基本数据类型进行值传递,对引用数据类型,创建一个新的对象,并复制其内容,此为深拷贝。
浅拷贝例子:
package se.copy;
import lombok.Data;
class Person implements Cloneable {
private String name;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Phone getPhone() {
return phone;
}
public void setPhone(Phone phone) {
this.phone = phone;
}
private Phone phone;
@Override
protected Object clone() throws CloneNotSupportedException {
return super.clone();
}
}
class Phone implements Cloneable {
private String name;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
@Override
protected Object clone() throws CloneNotSupportedException {
return super.clone();
}
}
public class ShallowCopy {
// 浅拷贝
public static void main(String[] args) throws CloneNotSupportedException {
Phone phone = new Phone();
phone.setName("小米");
// 创建一个Person对象(原对象)
Person person = new Person();
person.setName("hzk");
// 设置引用类型属性
person.setPhone(phone);
// 打印原对象的属性值
System.out.println(person);
System.out.println(person.getName());
System.out.println(person.getPhone());
System.out.println(person.getPhone().getName());
System.out.println("-----------------");
// 克隆一个Person对象(克隆对象)
Person copyPerson = (Person) person.clone();
// 打印克隆对象的属性值
System.out.println(copyPerson);
System.out.println(copyPerson.getName());
System.out.println(copyPerson.getPhone());
System.out.println(copyPerson.getPhone().getName());
// 浅拷贝由于会拷贝引用数据类型的地址,因此修改拷贝对象的值,其被拷贝对象的值也会跟着变化。反之,同理。
copyPerson.getPhone().setName("华为");
System.out.println("原对象的引用类型Phone值" + person.getPhone().getName());
System.out.println("克隆对象的引用类型Phone值" + copyPerson.getPhone().getName());
}
}
运行结果:
深拷贝例子:
package se.copy;
class Person1 implements Cloneable {
private String name;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Phone1 getPhone() {
return phone;
}
public void setPhone(Phone1 phone) {
this.phone = phone;
}
private Phone1 phone;
@Override
protected Object clone() throws CloneNotSupportedException {
// return super.clone();
//继续利用clone()方法,对该对象的引用类型变量再实现一次clone()方法。
// 要想深克隆 要不就是序列化和反序列化 要不就是继续clone
Person1 person = (Person1) super.clone();
person.setPhone((Phone1) person.getPhone().clone());
return person;
}
}
class Phone1 implements Cloneable {
private String name;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
@Override
protected Object clone() throws CloneNotSupportedException {
return super.clone();
}
}
public class DeepCopy {
// 深拷贝
public static void main(String[] args) throws CloneNotSupportedException {
Phone1 phone1 = new Phone1();
phone1.setName("小米");
Person1 person1 = new Person1();
person1.setName("hzk");
person1.setPhone(phone1);
System.out.println(person1);
System.out.println(person1.getName());
System.out.println(person1.getPhone());
System.out.println(person1.getPhone().getName());
System.out.println("-----------------");
Person1 copyPerson1 = (Person1) person1.clone();
System.out.println(copyPerson1);
System.out.println(copyPerson1.getName());
System.out.println(copyPerson1.getPhone());
System.out.println(copyPerson1.getPhone().getName());
System.out.println("-----------------");
// 深拷贝不会拷贝引用数据类型的地址(而是会创建一个新对象空间),因此修改拷贝对象的值,其被拷贝对象的值不会跟着变化。反之,同理。
copyPerson1.getPhone().setName("华为");
System.out.println("原对象的引用类型Phone值---" + person1.getPhone().getName());
System.out.println("克隆对象的引用类型Phone值---" + copyPerson1.getPhone().getName());
}
}
运行结果
深拷贝和浅拷贝在编程中都有重要的应用场景。
????????深拷贝主要用于需要修改原对象但又不希望影响原对象的场景。例如,当您需要使用一个对象作为参数传递给函数,同时又不想因为这个函数内部对对象的修改而改变原对象时,就需要使用深拷贝来创建一个新的独立的对象副本。此外,当您从数据库中读取一些数据并想在此基础上做一些改动,但又希望保持原数据的完整性时,深拷贝也是一个理想的选择。
????????相反,浅拷贝通常用于原始对象和拷贝对象需要共享相同数据的场景。例如,如果您有一个包含大量数据的对象,并且您只想复制该对象的一部分数据到另一个新的对象中,那么浅拷贝就非常适用,因为它只复制了对象的引用,而不是对象本身。此外,如果对象非常大,并且只需要偶尔进行修改,那么浅拷贝由于其较低的内存消耗可能会是更好的选择。
????????总的来说,深拷贝和浅拷贝的选择取决于具体的应用场景和需求,理解它们的区别对于正确处理对象和数组的复制至关重要。