在Java中,浅拷贝(Shallow Copy)和深拷贝(Deep Copy)是两种不同的对象复制方式。它们在处理对象内部引用类型的属性时表现不同。以下是对这两种拷贝方式的详细解释,并附有相应的代码示例。
浅拷贝(Shallow Copy)
定义
浅拷贝会创建一个新对象,但对于对象内部的引用类型属性,仍然复制其引用而不是创建一个新的独立对象。这意味着新对象和原对象共享这些引用类型的属性。
实现方式
实现Cloneable接口并重写clone()方法。
使用拷贝构造函数。
示例代码
// 定义一个类,包含引用类型属性
class Address {
String city;
public Address(String city) {
this.city = city;
}
@Override
public String toString() {
return city;
}
}
class Person implements Cloneable {
String name;
Address address;
public Person(String name, Address address) {
this.name = name;
this.address = address;
}
// 重写clone方法
@Override
protected Object clone() throws CloneNotSupportedException {
return super.clone(); // 浅拷贝
}
@Override
public String toString() {
return "Person{name='" + name + "', address=" + address + "}";
}
}
public class ShallowCopyExample {
public static void main(String[] args) {
try {
Address addr = new Address("Beijing");
Person person1 = new Person("Alice", addr);
Person person2 = (Person) person1.clone();
System.out.println("Before modification:");
System.out.println("person1: " + person1);
System.out.println("person2: " + person2);
// 修改person2的地址
person2.address.city = "Shanghai";
System.out.println("\nAfter modification:");
System.out.println("person1: " + person1); // person1的地址也被修改
System.out.println("person2: " + person2);
} catch (CloneNotSupportedException e) {
e.printStackTrace();
}
}
}
输出结果
Before modification:
person1: Person{name='Alice', address=Beijing}
person2: Person{name='Alice', address=Beijing}
After modification:
person1: Person{name='Alice', address=Shanghai}
person2: Person{name='Alice', address=Shanghai}
说明
在上述代码中,person1和person2共享同一个Address对象。当person2的address.city被修改时,person1的address.city也随之改变,这就是浅拷贝的特性。
深拷贝(Deep Copy)
定义
深拷贝会创建一个新对象,并且递归地复制对象内部的所有引用类型属性,使得新对象与原对象完全独立。
实现方式
实现Cloneable接口并重写clone()方法,在clone()方法中递归地克隆所有引用类型属性。
使用拷贝构造函数。
使用序列化(Serialization)。
示例代码
// 定义一个类,包含引用类型属性,并实现深拷贝
class Address implements Cloneable {
String city;
public Address(String city) {
this.city = city;
}
// 重写clone方法
@Override
protected Object clone() throws CloneNotSupportedException {
return super.clone();
}
@Override
public String toString() {
return city;
}
}
class Person implements Cloneable {
String name;
Address address;
public Person(String name, Address address) {
this.name = name;
this.address = address;
}
// 重写clone方法,实现深拷贝
@Override
protected Object clone() throws CloneNotSupportedException {
Person cloned = (Person) super.clone();
cloned.address = (Address) address.clone(); // 递归克隆引用类型属性
return cloned;
}
@Override
public String toString() {
return "Person{name='" + name + "', address=" + address + "}";
}
}
public class DeepCopyExample {
public static void main(String[] args) {
try {
Address addr = new Address("Beijing");
Person person1 = new Person("Alice", addr);
Person person2 = (Person) person1.clone();
System.out.println("Before modification:");
System.out.println("person1: " + person1);
System.out.println("person2: " + person2);
// 修改person2的地址
person2.address.city = "Shanghai";
System.out.println("\nAfter modification:");
System.out.println("person1: " + person1); // person1的地址不会被修改
System.out.println("person2: " + person2);
} catch (CloneNotSupportedException e) {
e.printStackTrace();
}
}
}
输出结果
Before modification:
person1: Person{name='Alice', address=Beijing}
person2: Person{name='Alice', address=Beijing}
After modification:
person1: Person{name='Alice', address=Beijing}
person2: Person{name='Alice', address=Shanghai}
说明
在上述代码中,person1和person2拥有独立的Address对象。当person2的address.city被修改时,person1的address.city保持不变,这就是深拷贝的特性。
总结
浅拷贝适用于对象内部没有引用类型属性,或者可以接受共享引用的情况。
深拷贝适用于需要完全独立的对象副本,确保原对象和新对象之间没有引用共享的情况。
标签:city,Java,name,person2,Person,person1,address,拷贝 From: https://blog.csdn.net/lxsxjsj/article/details/144301187