Java中的深拷贝和浅拷贝

在编程中,我们经常需要复制一个对象。在Java中,复制分为两种:浅拷贝和深拷贝。那么它们之间有什么区别呢?让我们一起来了解一下。

  1. 浅拷贝:创建一个新对象,然后将原对象的属性值复制到新对象中。如果属性是基本类型或不可变对象,那么直接复制;如果属性是引用类型,那么复制的是引用地址,而不是引用的对象。因此,对浅拷贝后的对象进行修改,会影响到原对象。

  2. 深拷贝:创建一个新对象,然后递归地将原对象的属性值复制到新对象中。对于引用类型的属性,会创建一个新的引用对象,并将原对象的引用地址复制到新对象中。这样,对深拷贝后的对象进行修改,不会影响到原对象。

为了更好地理解这两种拷贝方式,让我们通过一个简单的例子来说明。

假设有一个Person类,包含name(姓名)、age(年龄)和hobbies(爱好)三个属性。其中,hobbies是一个List<String>类型的列表。

import java.util.ArrayList;
import java.util.List;class Person implements Cloneable {String name;int age;List<String> hobbies;public Person(String name, int age, List<String> hobbies) {this.name = name;this.age = age;this.hobbies = hobbies;}@Overrideprotected Object clone() throws CloneNotSupportedException {Person clonedPerson = (Person) super.clone();clonedPerson.hobbies = new ArrayList<>(this.hobbies); // 深拷贝return clonedPerson;}
}

接下来,我们创建两个Person对象,并分别进行浅拷贝和深拷贝。

public class Main {public static void main(String[] args) throws CloneNotSupportedException {List<String> hobbies = new ArrayList<>();hobbies.add("篮球");hobbies.add("足球");Person person1 = new Person("张三", 25, hobbies);Person person2 = (Person) person1.clone(); // 浅拷贝Person person3 = (Person) person1.clone(); // 深拷贝}
}

现在,我们来看一下输出结果。首先,我们可以看到person1person2person3的基本信息都是一样的。但是,当我们修改person1的爱好时,发现person2的爱好并没有发生变化,而person3的爱好却发生了变化。这说明了什么呢?

原来,当我们对person1进行浅拷贝时,它的爱好实际上是指向了同一个列表。因此,当我们修改这个列表时,所有浅拷贝的对象都会受到影响。而当我们进行深拷贝时,每个对象都有自己的爱好列表,互不影响。这就是浅拷贝和深拷贝的区别。