深拷贝和浅拷贝是Java中常用的两个概念,用于描述对象的复制方式。在理解深拷贝和浅拷贝之前,我们先来了解一下对象的复制方式。
在Java中,对象赋值和对象复制是两个不同的概念。对象赋值是指将一个对象的引用赋值给另一个对象,它们指向同一个内存地址,修改其中一个对象会影响到另一个对象。而对象复制是指创建一个新的对象,将原对象的值拷贝到新对象中,新对象和原对象是两个独立的对象,修改一个对象不会影响到另一个对象。
那么,如何进行对象的复制呢?Java中提供了两种复制方式:浅拷贝和深拷贝。
浅拷贝
浅拷贝是指将对象复制一份,创建一个新的对象,新对象的成员变量和原对象的成员变量具有相同的值。但是,如果成员变量是引用类型,浅拷贝只会复制引用,不会复制引用的对象。也就是说,新对象和原对象的引用指向同一个内存地址,修改其中一个对象会影响到另一个对象。
下面我们通过一个示例来演示浅拷贝的过程:
class Person implements Cloneable {
private String name;
private int age;
private Address address;
public Person(String name, int age, Address address) {
this.name = name;
this.age = age;
this.address = address;
}
// 省略getters和setters
@Override
public Object clone() throws CloneNotSupportedException {
return super.clone();
}
}
class Address {
private String city;
public Address(String city) {
this.city = city;
}
// 省略getters和setters
}
public class ShallowCopyExample {
public static void main(String[] args) throws CloneNotSupportedException {
Address address = new Address("Beijing");
Person person1 = new Person("Alice", 20, address);
Person person2 = (Person) person1.clone();
System.out.println(person1.getName()); // Alice
System.out.println(person2.getName()); // Alice
person2.setName("Bob");
System.out.println(person1.getName()); // Alice
System.out.println(person2.getName()); // Bob
person2.getAddress().setCity("Shanghai");
System.out.println(person1.getAddress().getCity()); // Shanghai
System.out.println(person2.getAddress().getCity()); // Shanghai
}
}
在上面的例子中,我们创建了一个Person
类和一个Address
类。Person
类包含了一个引用类型的成员变量address
,而Address
类只有一个city
属性。
我们先创建了一个Person
对象person1
,并将其地址赋值给person2
。然后,我们修改person2
的姓名为"Bob",发现person1
的姓名并没有发生改变,这是因为姓名是基本数据类型,拷贝时直接复制了值。
接下来,我们修改person2
的地址为"Shanghai",发现person1
的地址也发生了改变。这是因为地址是引用类型,浅拷贝只复制了引用,而没有复制引用对象。所以,修改person2
的地址实际上修改了person1
的地址。
深拷贝
深拷贝是指将对象复制一份,创建一个新的对象,新对象和原对象完全独立,互不影响。深拷贝会递归地复制对象的所有引用类型成员变量及其引用的对象。
下面我们通过一个示例来演示深拷贝的过程:
class Person implements Cloneable {
private String name;
private int age;
private Address address;
public Person(String name, int age, Address address) {
this.name = name;
this.age = age;
this.address = address;
}
// 省略getters和setters
@Override
public Object clone() throws CloneNotSupportedException {
Person cloned = (Person) super.clone();
cloned.setAddress((Address) cloned.getAddress().clone());
return