在Java中,拷贝对象可以通过浅拷贝(Shallow Copy)和深拷贝(Deep Copy)实现。浅拷贝只复制对象的引用,而不复制对象本身。深拷贝则复制对象及其所有引用的对象,创建一个完全独立的副本。
浅拷贝是指复制对象的引用,而不是对象本身。对于对象内部的引用类型字段,浅拷贝会共享同一个引用。
class Address implements Cloneable {
String city;
Address(String city) {
this.city = city;
}
@Override
protected Object clone() throws CloneNotSupportedException {
return super.clone();
}
@Override
public String toString() {
return city;
}
}
class Person implements Cloneable {
String name;
int age;
Address address;
Person(String name, int age, Address address) {
this.name = name;
this.age = age;
this.address = address;
}
@Override
protected Object clone() throws CloneNotSupportedException {
return super.clone();
}
@Override
public String toString() {
return "Person{name='" + name + "', age=" + age + ", address=" + address + '}';
}
}
public class ShallowCopyExample {
public static void main(String[] args) throws CloneNotSupportedException {
Address address = new Address("New York");
Person person1 = new Person("John", 25, address);
Person person2 = (Person) person1.clone();
System.out.println("Before modifying address:");
System.out.println("Person 1: " + person1);
System.out.println("Person 2: " + person2);
person2.address.city = "San Francisco";
System.out.println("After modifying address:");
System.out.println("Person 1: " + person1);
System.out.println("Person 2: " + person2);
}
}
city 字段,实现 Cloneable 接口,并重写 clone 方法。name、age 和 address 字段,实现 Cloneable 接口,并重写 clone 方法。person2 的 address 后,person1 的 address 也会受到影响,因为它们共享同一个 Address 对象。深拷贝是指复制对象及其所有引用的对象,创建一个完全独立的副本。对于对象内部的引用类型字段,深拷贝会递归地复制它们。
class Address implements Cloneable {
String city;
Address(String city) {
this.city = city;
}
@Override
protected Object clone() throws CloneNotSupportedException {
return super.clone();
}
@Override
public String toString() {
return city;
}
}
class Person implements Cloneable {
String name;
int age;
Address address;
Person(String name, int age, Address address) {
this.name = name;
this.age = age;
this.address = address;
}
@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 + "', age=" + age + ", address=" + address + '}';
}
}
public class DeepCopyExample {
public static void main(String[] args) throws CloneNotSupportedException {
Address address = new Address("New York");
Person person1 = new Person("John", 25, address);
Person person2 = (Person) person1.clone();
System.out.println("Before modifying address:");
System.out.println("Person 1: " + person1);
System.out.println("Person 2: " + person2);
person2.address.city = "San Francisco";
System.out.println("After modifying address:");
System.out.println("Person 1: " + person1);
System.out.println("Person 2: " + person2);
}
}
Cloneable 接口并重写 clone 方法。clone 方法中,对 address 字段进行深拷贝(递归调用 address 的 clone 方法)。person2 的 address 后,person1 的 address 不会受到影响,因为它们拥有独立的 Address 对象。通过这些示例代码,可以看到浅拷贝和深拷贝在实现和效果上的差异。浅拷贝会共享对象的引用,而深拷贝则创建独立的对象副本。