java浅拷贝_浅谈java浅拷贝和深拷贝

前言:深拷贝和浅拷贝的区别是什么? 浅拷贝:被复制的对象的所有变量都含有原来对象相同的值,而所有的对其他对象的引用仍然指向原来的对象。换言之, 浅拷贝仅仅复制所考虑的对象,而不复制它所引用的对象。深拷贝:被复制对象的所有变量都含有与原来对象相同的值,而那些引用对象的变量将指向被复制过的新对象,而不再是原有 的那些被引用的对象。换言之,深拷贝把要复制的对象所引用的对象都复制了一遍。

浅拷贝

无论是浅拷贝还是深拷贝都要用到clone()方法,所有类都继承于Object,clone方法定义于Object类中但没有实现,

而如果要使用clone方法,根据源码则必须实现Cloneable接口,java.lang.Cloneable是一个标志性接口不包含任何方法,根据注释clone方法是由C或C++其他本地语言实现的。

* @return a clone of thisinstance.* @throws CloneNotSupportedException if the object's class does not

* support the {@code Cloneable} interface. Subclasses*that override the {@code clone} method can also* throw thisexception to indicate that an instance cannot*be cloned.*@see java.lang.Cloneable*/

protected native Object clone() throws CloneNotSupportedException;

实现浅拷贝:

packageyunche.test.copy;/*** @ClassName: Dog

* @Description:

*@author: yunche

* @date: 2018/08/25*/

public class Dog implementsCloneable

{publicString color;public intage;/*** 引用变量*/

publicErha erha;public static void main(String[] args) throwsCloneNotSupportedException

{

Dog d= newDog();

d.color="yellow";

d.age=2;

d.erha= newErha();

d.erha.name= "二哈";//此时clone方法为浅拷贝

Dog copyDog =(Dog)d.clone();

System.out.println(copyDog.color);

System.out.println(copyDog.age);

System.out.println(copyDog.erha.name);//hashcode不同,创建了新对象

System.out.println(d==copyDog);

System.out.println(d.hashCode());

System.out.println(copyDog.hashCode());//hashcode相同,没有创建新的erha对象,只是复制了引用

System.out.println(copyDog.erha==d.erha);

System.out.println(copyDog.erha.hashCode());

System.out.println(d.erha.hashCode());

}private static classErha

{

String name;

}

}

7c2827adaeef56fb8044c0af86103af3.png

深拷贝

深拷贝对于基本数据类型进行值传递,对引用数据类型,创建一个新的对象。并复制其内容。怎么实现深拷贝呢?通常的方案有两种:1.序列化这个对象,再反序列化回来,就可以得到这个新的对象,序列化的规则需要我们自己来写。2.重写clone方法,我们可以对其内部引用类型的变量,再进行一次clone()。

序列化方式

序列化需要实现Serializable接口。

packageyunche.test.copy;import java.io.*;/*** @ClassName: Dog

* @Description:

*@author: yunche

* @date: 2018/08/25*/

public class Dog implementsCloneable, Serializable

{publicString color;public intage;/*** 引用变量*/

publicErha erha;public static void main(String[] args) throwsCloneNotSupportedException

{

Dog d= newDog();

d.color="yellow";

d.age=2;

d.erha= newErha();

d.erha.name= "二哈";

Dog copyDog=(Dog)d.deepClone();

System.out.println(copyDog.color);

System.out.println(copyDog.age);

System.out.println(copyDog.erha.name);//hashcode不同,创建了新对象

System.out.println(d==copyDog);

System.out.println(d.hashCode());

System.out.println(copyDog.hashCode());//hashcode不同,创建新的erha对象,实现了深拷贝

System.out.println(copyDog.erha==d.erha);

System.out.println(copyDog.erha.hashCode());

System.out.println(d.erha.hashCode());

}publicObject deepClone()

{

File f= new File("dog.obj");

Object obj=null;try(FileOutputStream fos = newFileOutputStream(f);

ObjectOutputStream oos= newObjectOutputStream(fos);

FileInputStream fis= newFileInputStream(f);

ObjectInputStream ois= newObjectInputStream(fis))

{

oos.writeObject(this);

obj=ois.readObject();

}catch(FileNotFoundException e)

{

e.printStackTrace();

}catch(IOException e)

{

e.printStackTrace();

}catch(ClassNotFoundException e)

{

e.printStackTrace();

}returnobj;

}private static class Erha implementsSerializable

{

String name;

}

}

af2b9d92efc61d94f987c21acee357fa.png

重写clone

packageyunche.test.copy;import java.io.*;/*** @ClassName: Dog

* @Description:

*@author: yunche

* @date: 2018/08/25*/

public class Dog implementsCloneable

{publicString color;public intage;/*** 引用变量*/

publicErha erha;public static void main(String[] args) throwsCloneNotSupportedException

{

Dog d= newDog();

d.color="yellow";

d.age=2;

d.erha= newErha();

d.erha.name= "二哈";//重新clone方法,实现深拷贝

Dog copyDog =(Dog)d.clone();

System.out.println(copyDog.color);

System.out.println(copyDog.age);

System.out.println(copyDog.erha.name);//hashcode不同,创建了新对象

System.out.println(d==copyDog);

System.out.println(d.hashCode());

System.out.println(copyDog.hashCode());//hashcode不同,创建新的erha对象,实现了深拷贝

System.out.println(copyDog.erha==d.erha);

System.out.println(copyDog.erha.hashCode());

System.out.println(d.erha.hashCode());

}

@OverridepublicObject clone()

{try{

Dog dog= (Dog)super.clone();

dog.erha= (Erha) this.erha.clone();returndog;

}catch(CloneNotSupportedException e)

{

e.printStackTrace();

}return null;

}public static class Erha implementsCloneable

{

String name;

@OverridepublicObject clone()

{try{return super.clone();

}catch(CloneNotSupportedException e)

{

e.printStackTrace();

}return null;

}

}

}

ee00a3c8bba6b46c9c3b845e24a3aea6.png

参考资料

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值