Java中深拷贝和浅拷贝的区别
小明 Lv6
本文距离上次更新已过去 0 天,部分内容可能已经过时,请注意甄别。

👯‍♀️ 老虎老鼠傻傻分不清楚

在Java中,对象的拷贝可以分为深拷贝和浅拷贝。

  • 浅拷贝

是指创建一个新对象,然后将原对象的非静态字段值复制到新对象中。如果字段是基本数据类型,那么对应的值会被复制;如果字段是引用类型,那么只会复制引用而不是创建新的对象。这意味着原对象和拷贝对象将共享同一个引用对象。如果修改其中一个对象的引用类型字段,另一个对象也会受到影响。

深拷贝

是指创建一个新对象,并将原对象的所有字段(无论是基本数据类型还是引用类型)都复制到新对象中。这样,原对象和拷贝对象将完全独立,互不影响。

实现深拷贝有多种方式:

  1. 实现Cloneable接口,并重写clone()方法。在clone()方法中,对于引用类型的字段,需要创建新的对象并复制其内容。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
public class MyClass implements Cloneable {
private int intValue;
private String stringValue;
private MyObject objectValue;

@Override
public Object clone() throws CloneNotSupportedException {
MyClass cloned = (MyClass) super.clone();
cloned.objectValue = (MyObject) objectValue.clone();
return cloned;
}
}

public class MyObject implements Cloneable {
// ...
@Override
public Object clone() throws CloneNotSupportedException {
return super.clone();
}
}
  1. 使用序列化和反序列化实现深拷贝。将对象写入字节流,然后从字节流中读取数据创建一个新的对象。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
import java.io.*;

public class DeepCopyUtil {
public static <T extends Serializable> T deepCopy(T object) throws IOException, ClassNotFoundException {
ByteArrayOutputStream bos = new ByteArrayOutputStream();
ObjectOutputStream oos = new ObjectOutputStream(bos);
oos.writeObject(object);
oos.flush();

ByteArrayInputStream bis = new ByteArrayInputStream(bos.toByteArray());
ObjectInputStream ois = new ObjectInputStream(bis);
return (T) ois.readObject();
}
}

使用时可以调用DeepCopyUtil.deepCopy()方法来进行深拷贝。

需要注意的是,要实现深拷贝,对象及其所有引用类型字段都必须实现Cloneable接口或者可序列化(Serializable)。否则,在进行深拷贝时会抛出异常。

关注获取更多资源

image
 评论