Java中关于拷贝的知识点

Java中关于拷贝的知识点

​ 今天在刷leetcode题的时候,直接将一个对象赋值给另一个对象,然后对赋值后的对象进行操作,原对象也跟着发生了变化,因此,特地研究了一下关于Java中的拷贝。

从复制操作开始讲起

int a=10;
int b=a;

对于基本数据类型的复制,是将a的值复制一份,然后给b,此时,修改b的值,a的值并不会发生改变,这是值的复制。

ListNode a;
ListNode b;
b=a;

对于引用数据类型的复制,是将a的地址复制给b,所以此时b和a所指向的是同一个对象。

讲到这里,可能大家就会有点疑问了。为什么呢?

补充一下Java的内存机制

我们知道,JVM中分为栈区和堆区,对于基本数据类型,数据直接存放在栈区中;

对于引用数据类型,栈区中存放的是地址,而实际的值存放在堆区中。

了解了这个之后呢,我们就要接着讲一下引用拷贝和对象拷贝。

引用拷贝和对象拷贝

Teacher teacher = new Teacher("Taylor",26);
Teacher otherteacher = teacher;
System.out.println(teacher);
System.out.println(otherteacher);

输出结果
blog.Teacher@355da254
blog.Teacher@355da254

我们可以看到,二者的地址相同,所以两个变量指向的就是同一个对象,因此这就是引用拷贝,即

创建一个指向对象的引用变量的拷贝。

Teacher teacher = new Teacher("Swift",26);
Teacher otherteacher = (Teacher)teacher.clone();
System.out.println(teacher);
System.out.println(otherteacher);

输出结果
blog.Teacher@355da254
blog.Teacher@4dc63996

我们可以看到,二者的地址并不相同,因此是创建了新的对象,而不仅仅只是复制地址。这就是对象拷贝,即

创建对象本身的一个副本。

讲完了引用拷贝和对象拷贝,我们就要重点讲一下深拷贝和浅拷贝。

需要注意的是,深拷贝和浅拷贝都是对象拷贝。

浅拷贝和深拷贝

浅拷贝和深拷贝出现的背景:当一个引用数据类型中含有引用数据类型的属性。比如说最常见的自定义一个Person类,含有name和age两个属性,name是String类型,age是int类型。

由于age是基本数据类型, 那么对它的拷贝没有什么疑议,直接将一个4字节的整数值拷贝过来就行。但是name是String类型的, 它只是一个引用, 指向一个真正的String对象,那么对它的拷贝有两种方式: 直接将源对象中的name的引用值拷贝给新对象的name字段, 或者是根据原Person对象中的name指向的字符串对象创建一个新的相同的字符串对象,将这个新字符串对象的引用赋给新拷贝的Person对象的name字段。这两种拷贝方式分别叫做浅拷贝和深拷贝。

在这里插入图片描述

实现深拷贝

1.现在为了要在clone对象时进行深拷贝, 那么就要Clonable接口,覆盖并实现clone方法,除了调用父类中的clone方法得到新的对象, 还要将该类中的引用变量也clone出来。如果只是用Object中默认的clone方法,是浅拷贝的。

浅拷贝:
 @Override  
    protected Object clone() throws CloneNotSupportedException {  
        return super.clone();  
    }  
    
深拷贝:
 @Override  
    protected Object clone() throws CloneNotSupportedException {  
        Body newBody =  (Body) super.clone();  
        newBody.head = (Head) head.clone();  
        return newBody;  
        }
 即将源对象引用的对象也要clone一份。

但如果引用的对象中又包含引用数据类型,则此时的深拷贝是不完全的深拷贝,要继续重写引用的对象中的clone方法。

即将源对象引用的对象也要clone一份。

但如果引用的对象中又包含引用数据类型,则此时的深拷贝是不完全的深拷贝,要继续重写引用的对象中的clone方法。

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值