在Java中,深拷贝(Deep Copy)与浅拷贝(Shallow Copy)是两种拷贝对象的方式,它们在拷贝对象的方式上有很大不同。
浅拷贝
浅拷贝会创建一个新对象,但这个新对象的属性和原对象的属性完全相同。如果属性是基本数据类型,那么拷贝的是基本数据类型的值。如果属性是引用类型,那么拷贝的是引用类型的值,也就是对象的内存地址,因此新旧对象共享同一个引用对象。
浅拷贝的实现方式为:
1. 实现Cloneable接口并重写clone()
方法。
class Person implements Cloneable {
String name;
int age;
Address address;
public 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();
}
}
class Address {
String city;
public Address(String city) {
this.city = city;
}
}
public class Main {
public static void main(String[] args) throws CloneNotSupportedException {
Address address = new Address("福建省福州市");
Person person1 = new Person("adlx", 20, address);
Person person2 = (Person) person1.clone();
System.out.println(person1.address == person2.address); // true
}
}
深拷贝
深拷贝不仅复制对象本身,还会递归复制对象中所有引用的对象。这样新对象与原对象完全独立,新对象与原对象的任何更改都不会相互影响。
深拷贝的实现方式有:
1. 手动递归复制
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;
int age;
Address address;
public 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;
}
}
public class Main {
public static void main(String[] args) throws CloneNotSupportedException {
Address address = new Address("福建省福州市");
Person person1 = new Person("adlx", 20, address);
Person person2 = (Person) person1.clone();
System.out.println(person1.address == person2.address); // true
}
}
2. 使用序列化和反序列化
import java.io.*;
class Person implements Serializable {
String name;
int age;
Address address;
public Person(String name, int age, Address address) {
this.name = name;
this.age = age;
this.address = address;
}
public Person deepClone() throws IOException, ClassNotFoundException {
ByteArrayOutputStream bos = new ByteArrayOutputStream();
ObjectOutputStream oos = new ObjectOutputStream(bos);
oos.writeObject(this);
ByteArrayInputStream bis = new ByteArrayInputStream(bos.toByteArray());
ObjectInputStream ois = new ObjectInputStream(bis);
return (Person) ois.readObject();
}
}
class Address implements Serializable {
String city;
public Address(String city) {
this.city = city;
}
}
public class Main {
public static void main(String[] args) throws IOException, ClassNotFoundException {
Address address = new Address("福建省福州市");
Person person1 = new Person("adlx", 20, address);
Person person2 = person1.deepClone();
System.out.println(person1.address == person2.address); // false
}
}