深拷贝和浅拷贝
深拷贝和浅拷贝
1.类型
拷贝一般分为二大类 引用拷贝 和 对象拷贝,我们通常讲的深拷贝
和浅拷贝
都属于对象拷贝。
2.引用拷贝
定义:顾名思义,即是对引用地址的拷贝,说明引用地址一样,指向堆中的对象是同一个对象。
如果对一个对象进行改变,其他对象也会跟着改变。
Teacher teacher = new Teacher("Taylor",26);
// 这一步结束后otherteacher的地址和teacher的地址相同
Teacher otherteacher = teacher;
System.out.println(teacher);
System.out.println(otherteacher);
/**
* @output
* blog.Teacher@355da254
* blog.Teacher@355da254
*
/*
结果分析:由输出结果可以看出,它们的地址值是相同的,那么它们肯定是同一个对象。teacher和otherteacher的只是引用而已,他们都指向了一个相同的对象Teacher(“Taylor”,26)。这就叫做引用拷贝。
3.对象拷贝
定义:对象拷贝指 对某一对象进行拷贝,是创建了一个全新的对象,也就是内存中存在二个不同地址的对象,这二个对象的基本数据类型变量的内容值都是一样的,但所包含的对象变量的地址可能一样可能不一样,浅拷贝与深拷贝的区别就在这里
public static class Person implements Cloneable{
public String name;
public int age;
/** Person类中不仅仅有像name,age这样的基本数据类型也存在着house这样的对象变量
浅拷贝是只拷贝Person中的基本数据类型,而不拷贝对象
深拷贝是将所有类型的数据都拷贝
通俗的来说深拷贝比浅拷贝拷贝的更加彻底
*/
public House house;
public Person(String name, int age, House house) {
this.name = name;
this.age = age;
this.house = house;
}
@Override
public Object clone() throws CloneNotSupportedException {
return super.clone();
}
}
}
注意:clone的使用需要先在Teacher类中实现Cloneable接口,然后重写之中的clone方法
4.浅拷贝
定义:当前对象里包含有对象变量,如果复制的对象中的对象变量和原对象里的对象地址值是相同的,即引用拷贝,则称之为浅拷贝。我们也可以称之为部分拷贝,即拷贝的不彻底。
public static void main(String[] args) {
Person person1=new Person("A",20, new House("aa"));
try {
Person person2= (Person) person1.clone();
System.out.println("persion1 = " + person1+" house = "+person1.house);
System.out.println("persion2 = " + person2+" house = "+person2.house);
} catch (CloneNotSupportedException e) {
e.printStackTrace();
}
}
/**
* output:
* persion1 = Person@402a079c house = House@59ec2012
* persion2 = Person@4cf777e8 house = House@59ec2012
*/
可以看到我们对Person1进行了clone,person2的内存地址和person1的不一样,说明这是一个新对象,然而在看对象House,内存地址是一样的,说明对于成员变量只进行了内存引用。这个就是浅拷贝。
总结:虽然对象进行了拷贝,但内部变量没有完全进行拷贝。这就是浅拷贝,即拷贝的不彻底
5.深拷贝
当前对象里包含有对象变量,如果复制的对象中的对象变量和原对象里的对象地址值是不同的,即创建了一个新的对象,则称之为深拷贝。我们也可以称之为完全拷贝,内部进行了彻底拷贝。
现在我们对 clone方法做一些修改
public class Person implements Cloneable {
public String name;
public int age;
public House house;
public Person(String name, int age, House house) {
this.name = name;
this.age = age;
this.house = house;
}
@Override
public Object clone() throws CloneNotSupportedException {
Person person = (Person) super.clone();
//在原有的基础上 clone了成员变量对象
person.house = (House) person.house.clone();
return person;
}
}
class House implements Cloneable {
public String address;
public House(String address) {
this.address = address;
}
//实现clone方法
@Override
protected Object clone() throws CloneNotSupportedException {
return super.clone();
}
}
/**
* output:
* persion1 =Person@402a079c house = House@59ec2012
* persion2 = Person@4cf777e8 house = House@2f686d1f
*/
可以看到不仅Person对象内存地址不一样,House的内存地址也不一样了,这说明Person1和Person2的内容,成员变量也完全不相同了。
总结:一个对象进行了clone,不仅仅自身clone了一个新的,其内部的成员变量也都clone了一个新的,这就是深拷贝。
所以,如果一个对象中仅包含基本数据类型,则浅拷贝和深拷贝则没区别。如果一个对象中包含了对象变量,则对这些对象变量的拷贝 就成了 浅拷贝和深拷贝的区别。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 25岁的心里话
· 闲置电脑爆改个人服务器(超详细) #公网映射 #Vmware虚拟网络编辑器
· 零经验选手,Compose 一天开发一款小游戏!
· 因为Apifox不支持离线,我果断选择了Apipost!
· 通过 API 将Deepseek响应流式内容输出到前端