Java知识速记:深拷贝与浅拷贝
Java知识速记:深拷贝与浅拷贝
什么是浅拷贝?
浅拷贝指的是创建一个新对象,但新对象的属性值是对原对象属性值的引用。当原对象的属性是基本类型时,浅拷贝能够直接复制其值;当属性是对象时,仅复制引用,实际数据仍然共享。
浅拷贝的实现
在 Java 中,可以通过 clone()
方法实现浅拷贝。下面是一个简单的示例:
class Person implements Cloneable {
String name;
Address address;
Person(String name, Address address) {
this.name = name;
this.address = address;
}
@Override
protected Object clone() throws CloneNotSupportedException {
return super.clone();
}
}
class Address {
String city;
Address(String city) {
this.city = city;
}
}
public class ShallowCopyExample {
public static void main(String[] args) throws CloneNotSupportedException {
Address address = new Address("北京");
Person person1 = new Person("小明", address);
Person person2 = (Person) person1.clone();
System.out.println(person1.address.city); // 输出: 北京
person2.address.city = "上海"; // 修改 person2 的地址
System.out.println(person1.address.city); // 输出: 上海
}
}
在上面的代码中,person2
是 person1
的浅拷贝。修改 person2
的地址会影响到 person1
,因为两者共享同一个 Address
对象的引用。
什么是深拷贝?
深拷贝则不同,它会创建一个新对象并复制原对象及其所有属性的完整副本,包括嵌套的对象。深拷贝确保了原对象和拷贝对象之间的完全独立。
深拷贝的实现
深拷贝可以通过手动方式实现,或者利用序列化技术。以下是使用手动方式实现深拷贝的示例:
class Person implements Cloneable {
String name;
Address address;
Person(String name, Address address) {
this.name = name;
this.address = address;
}
@Override
protected Object clone() throws CloneNotSupportedException {
Person cloned = (Person) super.clone();
cloned.address = new Address(this.address.city); // 深拷贝 Address 对象
return cloned;
}
}
class Address {
String city;
Address(String city) {
this.city = city;
}
}
public class DeepCopyExample {
public static void main(String[] args) throws CloneNotSupportedException {
Address address = new Address("北京");
Person person1 = new Person("小明", address);
Person person2 = (Person) person1.clone();
System.out.println(person1.address.city); // 输出: 北京
person2.address.city = "上海"; // 修改 person2 的地址
System.out.println(person1.address.city); // 仍然输出: 北京
}
}
在这个深拷贝的示例中,person2
拷贝了 person1
的 Address
对象,但两者并不共享同一个地址,修改 person2
的地址不会影响 person1
。
深拷贝与浅拷贝的选择
在实际开发中,选择使用深拷贝还是浅拷贝主要取决于具体的场景:
-
使用浅拷贝:当对象的属性是不可变对象(例如字符串),或者这些属性不需要独立的副本时,浅拷贝能够提供更好的性能。
-
使用深拷贝:当对象包含复杂的嵌套引用结构,并且需要确保每个对象的独立性时,深拷贝是唯一的选择。