QE:什么是深拷贝,什么是浅拷贝
AS:
在 Java 中,深拷贝(Deep Copy)和浅拷贝(Shallow Copy)是对象复制的两种不同方式,它们的区别在于复制对象时是否复制对象的所有层级。
-
浅拷贝(Shallow Copy):
- 浅拷贝是指只复制对象本身,而不复制对象内部的成员对象。
- 在浅拷贝中,如果对象内部有引用类型的成员变量,复制的是引用,而不是引用指向的对象本身。
- 因此,浅拷贝得到的对象与原始对象共享同一个引用类型成员对象,对其中一个对象的引用类型成员的修改会影响另一个对象。
-
深拷贝(Deep Copy):
- 深拷贝是指复制对象本身,并且递归复制对象内部所有的引用类型成员对象,直到所有层级的对象都复制完成。
- 在深拷贝中,复制的是引用类型成员对象的副本,而不是引用本身。
- 因此,深拷贝得到的对象与原始对象完全独立,对其中一个对象的引用类型成员的修改不会影响另一个对象。
这么说可能还是有点抽象,接下来笔者将通过代码演示
代码演示
class Money implements Cloneable
{
double m=19.9;
@Override
protected Object clone() throws CloneNotSupportedException {
return super.clone();
}
}
class Person implements Cloneable
{
public String name;
public int age;
Money money=new Money();
public Person(String name, int age) {
this.name = name;
this.age = age;
}
@Override
public String toString() {
return "Person{" +
"name='" + name + '\'' +
", age=" + age +
'}';
}
@Override
protected Object clone() throws CloneNotSupportedException
{
Person tmp= (Person) super.clone();
tmp.money = (Money) this.money.clone();
//核心步骤,复制第二份money
return tmp;
// 深拷贝写法,创建一个tmp,然后复制,然后在复制的类中接着复制money
// return super.clone();
// or Person tmp= (Person) super.clone();
// return tmp;
// 浅拷贝写法
}
// 所有类默认继承于object类,所以说,可以通过super调用clone方法;
}
public class test1
{
public static void main(String[] args) throws CloneNotSupportedException {
Person p1=new Person("zhangsan",20);
Person p2=(Person) p1.clone();
// 向下转型
System.out.println(p1.money.m);
System.out.println(p2.money.m);
Money mo=new Money();
p1.money.m=99.9;
System.out.println(p1.money.m);
System.out.println(p2.money.m);
}
}
这是完整代码,接下来,笔者将逐步说明
类代码
首先是创建两个类,并且,实现 Cloneable
接口并重写 clone()
方法
class Money implements Cloneable
{
double m=19.9;
@Override
protected Object clone() throws CloneNotSupportedException {
return super.clone();
}
}
class Person implements Cloneable
{
public String name;
public int age;
Money money=new Money();
public Person(String name, int age) {
this.name = name;
this.age = age;
}
@Override
public String toString() {
return "Person{" +
"name='" + name + '\'' +
", age=" + age +
'}';
}
@Override
protected Object clone() throws CloneNotSupportedException
{
Person tmp= (Person) super.clone();
tmp.money = (Money) this.money.clone();
//核心步骤,复制第二份money
return tmp;
// 深拷贝写法,创建一个tmp,然后复制,然后在复制的类中接着复制money
// return super.clone();
// or Person tmp= (Person) super.clone();
// return tmp;
// 浅拷贝写法
}
// 所有类默认继承于object类,所以说,可以通过super调用clone方法;
}
深浅拷贝代码区别
我们首先看浅拷贝
@Override
protected Object clone() throws CloneNotSupportedException
{
return super.clone();
}
@Override
protected Object clone() throws CloneNotSupportedException
{
Person tmp= (Person) super.clone();
// tmp.money = (Money) this.money.clone();
return tmp;
}
我们可以看到,这是两种浅拷贝写法,浅拷贝只是拷贝了一份Person类,并没有额外去拷贝Money类,所以,当我们在主函数中修改时,m的值会产生一样的变化.
深拷贝代码
@Override
protected Object clone() throws CloneNotSupportedException
{
Person tmp= (Person) super.clone();
tmp.money = (Money) this.money.clone();
// 核心步骤,复制第二份money
return tmp;
}
深拷贝中,唯一的区别就是,将tmp中的money又复制拷贝了一份.让tmp与原始的对象完全独立了
图示例
如果还不太懂,可以看这张图
图一是浅拷贝,图二是深拷贝
结尾
java还是有点难学的!!!