Java中的深拷贝与浅拷贝
时间: 2025-05-31 14:23:12 浏览: 9
### Java 深拷贝与浅拷贝的区别及实现方法
#### 浅拷贝 (Shallow Copy)
浅拷贝是指创建一个新的对象,这个新对象会复制原对象中的基本数据类型的变量值,而对于引用类型的数据,则只复制其引用地址而不复制实际的对象。这意味着,如果原始对象中有任何引用类型的成员变量,在浅拷贝之后,这些成员变量仍然指向同一内存位置[^1]。
例如:
```java
class Teacher implements Cloneable {
String name;
int age;
public Object clone() throws CloneNotSupportedException {
return super.clone();
}
}
public class Main {
public static void main(String[] args) throws CloneNotSupportedException {
Teacher teacher = new Teacher();
teacher.name = "Donglin";
teacher.age = 28;
Teacher otherTeacher = (Teacher) teacher.clone();
System.out.println(teacher == otherTeacher); // false, 不同的对象
System.out.println(teacher.name == otherTeacher.name); // true, 字符串常量池共享
}
}
```
上述代码展示了浅拷贝的行为:`otherTeacher` 是 `teacher` 的副本,但对于字符串 `name` 和整型 `age` 而言,它们的值被直接复制;而如果是更复杂的对象(如数组或其他类),则仅复制引用地址[^5]。
---
#### 深拷贝 (Deep Copy)
深拷贝不仅复制了对象本身,还递归地复制了该对象所包含的所有子对象。因此,即使在源对象和目标对象之间存在嵌套层次关系,也不会因为引用共享而导致意外修改[^2]。
一种常见的实现方式是利用序列化机制完成深拷贝操作。具体过程如下:先将对象序列化成字节流形式存储到临时缓冲区中,再反序列化还原为独立的新对象实例[^4]。
以下是基于序列化的深拷贝示例:
```java
import java.io.*;
class Address implements Serializable {
String city;
public Address(String city) {
this.city = city;
}
}
class Person implements Serializable {
String name;
transient int age; // 使用transient关键字忽略某些字段不参与序列化
Address address;
public Person(String name, int age, Address address) {
this.name = name;
this.age = age;
this.address = address;
}
@Override
public String toString() {
return "Person{name='" + name + "', age=" + age + ", address=" + address.city + "}";
}
public Person deepCopy() 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();
}
}
public class DeepCopyExample {
public static void main(String[] args) throws Exception {
Address addr = new Address("Beijing");
Person person = new Person("Alice", 30, addr);
Person copiedPerson = person.deepCopy(); // 创建深拷贝
System.out.println(person.toString()); // 输出: Person{name='Alice', age=30, address=Beijing}
System.out.println(copiedPerson.toString());// 输出: Person{name='Alice', age=0, address=Beijing} -> 年龄未保留因标记为transient
addr.city = "Shanghai"; // 修改原对象属性
System.out.println(person.toString()); // 输出: Person{name='Alice', age=30, address=Shanghai}
System.out.println(copiedPerson.toString());// 输出不变: Person{name='Alice', age=0, address=Beijing}
}
}
```
在这个例子中可以看到,当改变原来的 `Address` 对象的城市名称时,不会影响已经进行了深拷贝后的 `copiedPerson` 所持有的地址信息。
---
#### 总结对比表
| 特性 | 浅拷贝 | 深拷贝 |
|-----------------|-------------------------------------|---------------------------------------|
| **定义** | 复制基础数据类型值,引用类型指针 | 完全克隆整个对象及其内部所有组件 |
| **性能开销** | 较低 | 高 |
| **适用场景** | 数据简单或无需完全隔离的情况 | 当需要彻底断绝两个对象间联系的时候 |
---
阅读全文
相关推荐

















