在Java中,深拷贝(Deep Copy)和浅拷贝(Shallow Copy)是两个常见的对象拷贝方式。它们的主要区别在于它们处理对象中的引用类型字段的方式。
1. 浅拷贝(Shallow Copy)
浅拷贝仅拷贝对象本身以及对象中所有的基本数据类型字段,对于引用类型字段(如对象、数组等),仅复制其引用(即指针),而不复制实际的对象。这意味着原对象和拷贝对象中的引用类型字段指向同一个内存地址,因此改变一个对象中的引用类型字段可能会影响到另一个对象。
实现方式:
- 实现
Cloneable
接口并重写clone()
方法。
代码示例:
class Address {
String city;
public Address(String city) {
this.city = city;
}
}
class Person implements Cloneable {
String name;
Address address;
public Person(String name, Address address) {
this.name = name;
this.address = address;
}
@Override
protected Object clone() throws CloneNotSupportedException {
return super.clone(); // 浅拷贝
}
}
public class ShallowCopyExample {
public static void main(String[] args) throws CloneNotSupportedException {
Address address = new Address("New York");
Person person1 = new Person("John", address);
Person person2 (Person) person1.clone();
System.out.println(person1.address.city); // New York
System.out.println(person2.address.city); // New York
person2.address.city = "San Francisco";
System.out.println(person1.address.city); // San Francisco
System.out.println(person2.address.city); // San Francisco
}
}
应用场景:
浅拷贝适用于对象结构简单且不包含复杂的嵌套对象的情况。因为浅拷贝的速度较快,适合对性能有较高要求但不涉及深层嵌套结构的场景。
2. 深拷贝(Deep Copy)
深拷贝不仅拷贝对象本身,还会递归地拷贝对象中所有引用类型字段所指向的对象。这意味着原对象和拷贝对象中的引用类型字段互不影响,修改一个对象中的引用类型字段不会影响到另一个对象。
实现方式:
- 重写
clone()
方法,手动拷贝所有的引用类型字段。 - 使用序列化和反序列化实现深拷贝。
代码示例:
class Address implements Cloneable {
String city;
public Address(String city) {
this.city = city;
}
@Override
protected Object clone() throws CloneNotSupportedException {
return super.clone();
}
}
class Person implements Cloneable {
String name;
Address address;
public Person(String name, Address address) {
this.name = name;
this.address = address;
}
@Override
protected Object clone() throws CloneNotSupportedException {
Person clonedPerson = (Person) super.clone();
clonedPerson.address = (Address) address.clone(); // 深拷贝
return clonedPerson;
}
}
public class DeepCopyExample {
public static void main(String[] args) throws CloneNotSupportedException {
Address address = new Address("New York");
Person person1 = new Person("John", address);
Person person2 = (Person) person1.clone();
System.out.println(person1.address.city); // New York
System.out.println(person2.address.city); // New York
person2.address.city = "San Francisco";
System.out.println(person1.address.city); // New York
System.out.println(person2.address.city); // San Francisco
}
}
应用场景:
深拷贝适用于对象结构复杂且包含多个嵌套引用类型字段的场景,尤其是在这些引用类型字段是可变对象时。深拷贝确保拷贝后的对象与原对象完全独立,不会互相影响。
总结
- 浅拷贝:仅复制对象及其基本数据类型字段,引用类型字段只复制引用。适用于简单的对象结构。
- 深拷贝:复制对象及其所有引用类型字段所指向的对象。适用于复杂对象结构,确保深层次的独立性。
根据具体需求选择合适的拷贝方式可以有效地避免不必要的副作用并提高程序的性能。
评论 (0)