Java对象深拷贝与浅拷贝的区别
目录
- 一、浅拷贝
- 示例代码
- 输出结果
- 代码解析
- 二、深拷贝
- 示例代码
- 输出结果
- 代码解析
- 三、总结
在 Java 编程中,深拷贝和浅拷贝是对象复制的两种方式,它们在处理对象的引用类型时表现不同。
一、浅拷贝
浅拷贝是指创建一个新对象,并将原对象的字段值复制到新对象中。如果字段是基本数据类型,则直接复制其值;如果字段是引用类型,则复制的是引用(即两个对象的引用字段指向同一个内存地址)。
示例代码
class Address {
String street;
String city;
public Address(String street, String city) {
this.street = street;
this.city = city;
}
}
class Person {
String name;
Address address;
public Person(String name, Address address) {
this.name = name;
this.address = address;
}
}
public class ShallowCopyExample {
public static void main(String[] args) {
Address originalAddress = new Address("123 Main St", "Anytown");
Person originalPerson = new Person("John Doe", originalAddress);
// 浅拷贝
Person copiedPerson = new Person(originalPerson.name, originalPerson.address);
// 修改拷贝对象的地址
copiedPerson.address.city = "New City";
System.out.println("Original person's address: " + originalPerson.address.city);
System.out.println("Copied person's address: " + copiedPerson.address.city);
}
}
输出结果
Original person's address: New City
Copied person's address: New City
代码解析
在上述代码中,copiedPerson
是通过浅拷贝创建的。它复制了 originalPerson
的 name
字段和 address
引用。由于 address
是引用类型,两个 Person
对象的 address
字段指向同一个 Address
对象。因此,当修改 copiedPerson
的地址时,originalPerson
的地址也会发生变化。
二、深拷贝
深拷贝是指创建一个新对象,并将原对象的字段值复制到新对象中。如果字段是引用类型,则递归地创建该引用对象的深拷贝,确保新对象与原对象在内存中完全独立。
示例代码
class Address implements Cloneable {
String street;
String city;
public Address(String street, String city) {
this.street = street;
this.city = city;
}
@Override
public Address clone() {
try {
return (Address) super.clone();
} catch (CloneNotSupportedException e) {
throw new AssertionError();
}
}
}
class Person implements Cloneable {
String name;
Address address;
public Person(String name, Address address) {
this.name = name;
this.address = address;
}
@Override
public Person clone() {
try {
Person cloned = (Person) super.clone();
cloned.address = address.clone();
return cloned;
} catch (CloneNotSupportedException e) {
throw new AssertionError();
}
}
}
public class DeepCopyExample {
public static void main(String[] args) {
Address originalAddress = new Address("123 Main St", "Anytown");
Person originalPerson = new Person("John Doe", originalAddress);
// 深拷贝
Person copiedPerson = originalPerson.clone();
// 修改拷贝对象的地址
copiedPerson.address.city = "New City";
System.out.println("Original person's address: " + originalPerson.address.city);
System.out.println("Copied person's address: " + copiedPerson.address.city);
}
}
输出结果
Original person's address: Anytown
Copied person's address: New City
代码解析
在上述代码中,copiedPerson
是通过深拷贝创建的。它复制了 originalPerson
的 name
字段,并创建了 address
对象的深拷贝。因此,两个 Person
对象的 address
字段指向不同的 Address
对象。修改 copiedPerson
的地址不会影响 originalPerson
的地址。
三、总结
浅拷贝只复制对象的直接字段,对于引用类型字段,复制的是引用,因此原对象和拷贝对象的引用字段指向同一个对象。深拷贝则递归地复制对象及其引用的所有对象,确保原对象和拷贝对象完全独立。在实际开发中,根据需求选择合适的拷贝方式。