Java深拷贝和浅拷贝
是什么
- 浅拷贝:通常来讲,一个对象使用
Object.clone()
方法属于浅拷贝,浅拷贝只拷贝基本类型和String
类型的成员变量。它的特点是,一个对象如果有引用类型的成员变量(String
除外),浅拷贝只是拷贝这个成员变量的引用到新的对象,即两个对象中的这两个成员变量,共用一个内存地址。随之带来的问题是,一个对象改变了这个成员变量的值,另一个对象的该成员变量也随之修改。 - 深拷贝:深拷贝则是给拷贝后的该引用变量开辟了一个新的内存空间,也就是该引用变量与拷贝前的引用变量的内存地址不一样了。 这样的话,修改不会影响到彼此。
需要明确的是,两种拷贝后两个对象是不相等的。
举例说明:
浅拷贝
首先,要使用clone
方法需要实现Cloneable
接口,并重写clone
方法,并修改方法为public
。
@Data
@AllArgsConstructor
class Person implements Cloneable {
private String name;
private int age;
private Dog dog;
@Override
public Object clone() throws CloneNotSupportedException {
return super.clone();
}
}
@Data
@AllArgsConstructor
class Dog {
private String color;
}
public class CopyTest {
public static void main(String[] args) throws CloneNotSupportedException {
Person person = new Person("Tom", 10, new Dog("black"));
Person clone = (Person) person.clone();
System.out.println("person == clone : " + (person == clone));
System.out.println("===== clone对象修改自身属性 =====");
clone.setName("Bob");
clone.setAge(30);
clone.getDog().setColor("white");
System.out.println(person);
System.out.println(clone);
}
}
person == clone : false
===== clone对象修改自身属性 =====
Person(name=Tom, age=10, dog=Dog(color=white))
Person(name=Bob, age=30, dog=Dog(color=white))
这就是浅拷贝,clone
对象修改了dog
,person
对象中的dog
也被修改了,因为两个引用变量指向同一个内存地址。
如何实现深拷贝呢?
方法一:把引用类型的成员变量再clone一次。
@Data
@AllArgsConstructor
class Person implements Cloneable {
private String name;
private int age;
private Dog dog;
@Override
public Object clone() throws CloneNotSupportedException {
Person clone = (Person) super.clone();
clone.setDog((Dog) clone.getDog().clone());
return clone;
}
}
这种方式,Dog
也要实现Cloneable
。
方法二:参考网上的工具类。值得注意的是 Spring 和 Apache 的BeanUtils
都是浅拷贝。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 25岁的心里话
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· 闲置电脑爆改个人服务器(超详细) #公网映射 #Vmware虚拟网络编辑器
· ollama系列01:轻松3步本地部署deepseek,普通电脑可用