Java中深拷贝和浅拷贝的研究

Java中深拷贝和浅拷贝的研究

以这个问题开篇吧:String类型的拷贝到底是浅拷贝还是深拷贝???

准备说写一个程序来测试下,发现String没有实现Cloneable接口,也没有重写clone方法

String str1="wuanghao";
//String str2=str1.clone();//报错
String str3=str1;//复制引用

String不是基本数据类型,String也没有实现Cloneable接口,也就是说只能复制引用。

那么在修改克隆之后的对象str3之后,会不会将原来的值str1也改变了?答案是不会改变

public class StringCopy {
    public static void main(String [] args){
        String str1="wuanghao";
        //String str2=str1.clone();
        String str2=str1;
        str2=str2+"wo";
        System.out.println(str1);
    }
}

用以上代码测试,对象str1是没有被改变的。

原因或许大家都知道
因为String是在内存中不可以被改变的对象,就比如说在for大量循环中不推荐使用+的方式来拼凑字符串一样,每次使用+都会新分配一块内存,不在原来上修改,原来的没有指向它的引用,会被回收。所以克隆相当于1个String内存空间有两个引用,当修改其中的一个值的时候,会新分配一块内存用来保存新的值,这个引用指向新的内存空间,原来的String因为还存在指向他的引用,所以不会被回收,这样,虽然是复制的引用,但是修改值的时候,并没有改变被复制对象的值。

就是因为:虽然是复制的引用,但是修改值的时候,并没有改变被复制对象的值
所以在很多情况下,我们可以把String在clone的时候和基本类型做相同的处理,只是在equal时注意一些就行了。

这样关于上面问题的答案就是:String类型是浅拷贝,但是一般把它当深拷贝对待。

1.浅拷贝与深拷贝概念

(1)浅拷贝(浅克隆)

浅拷贝又叫浅复制,将对象中的所有字段复制到新的对象(副本)中。其中,值类型字段(java中8中原始类型)的值被复制到副本中后,在副本中的修改不会影响到源对象对应的值。而引用类型的字段被复制到副本中的还是引用类型的引用,而不是引用的对象,在副本中对引用类型的字段值做修改会影响到源对象本身。
浅拷贝简单归纳就是只复制一个对象,对象内部存在指向其他对象,数组或引用则不复制。

(2)深拷贝(深克隆)

将对象中的所有字段复制到新的对象中。不过,无论是对象的值类型字段,还是引用类型字段,都会被重新创建并赋值,对于副本的修改,不会影响到源对象本身。
深拷贝简单归纳就是对象内部引用的对象均复制。

2.Java中的clone()方法

(1)clone()方法将对象复制了一份并返回给调用者。一般而言,clone()方法满足下面规范:
①对任何的对象x,都有x.clone() != x;//克隆对象与原对象不是同一个对象
②对任何的对象x,都有x.clone().getClass()== x.getClass();//克隆对象与原对象的类型一样
③如果对象x的equals()方法定义恰当,那么x.clone().equals(x);应该成立。
(2)Java中对象的克隆
clone()方法是在Object中定义的,而且是protected的,只有实现了Cloneable接口的类才可以在其实例上调用clone()方法,否则会抛出CloneNotSupportException。
为了获取对象的一份拷贝,我们可以利用Object类的clone()方法,也可以实现Cloneable接口,覆盖基类的clone()方法,在clone()方法中,调用super.clone()。
Cloneable接口是一个标记接口,也就是没有任何内容,定义如下:

package java.lang;
pubilc interface Cloneable{
   
}

例子1:对象中只含基本数据类型(完成的是深拷贝)

Student类:只含基本数据类型和Sting类型

package com.wrh.copy;
//将一个类实现Cloneable接口,并将Object中clone()方法的权限Protected换成public
//这个类的对象就可以被拷贝
public class Student implements Cloneable{
   
    
  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值