java cloneable 深拷贝_Java中的Cloneable接口与深拷贝、浅拷贝

Cloneable接口是一个标记接口,也就是没有任何内容,定义如下:

这里分析一下这个接口的用法,clone方法是在Object种定义的,而且是protected型的,只有实现了这个接口,才可以在该类的实例上调用clone方法,否则会抛出CloneNotSupportException。Object中默认的实现是一个浅拷贝,也就是表面拷贝,如果需要实现深层次拷贝的话,必须对类中可变域生成新的实例。

Object提供了一个对象拷贝的默认方法clone方法,但是该方法是有缺陷的,它提供了一种浅拷贝方式,也就是它并不会把对象所有属性全部拷贝一份,而是有选择性的拷贝,拷贝规则如下:

1、基本类型

如果变量是基本类型,则拷贝其值,比如:int、float、long等。

2、String字符串

这个比较特殊,拷贝的是地址,是个引用,但是在修改的时候,它会从字符串池(String

Pool)中重新生成新的字符串,原有的字符串对象保持不变,此处可以认为String是个基本类型。

3、对象

如果变量时一个实例对象,则拷贝地址引用,也就是说此时新拷贝出的对象与原有对象共享该实例变量,不受访问权限的限制。这在Java中很疯狂,因为它突破了访问权限的定义,一个private修饰的变量,竟然可以被两个实例对象访问。

Cloneable接口如下:如果调用Object的clone方法,没有实现Cloneable接口,则会抛出CloneNotSupportedException

69c5a8ac3fa60e0848d784a6dd461da6.pngpackagejava.lang;/*** Invoking Object‘s clone method on an instance that does not implement the

* Cloneable interface results in the exception

* CloneNotSupportedException being thrown.

*

*@authorunascribed

*@seejava.lang.CloneNotSupportedException

*@seejava.lang.Object#clone()

*@sinceJDK1.0*/

public interfaceCloneable {

}

69c5a8ac3fa60e0848d784a6dd461da6.png

关于clone方法的浅拷贝的一个demo,可以看出虽然是两个不同的ShallowCopy对象,但是对于他们的非基本数据类型的成员变量是属于同一个引用。因此是浅拷贝

69c5a8ac3fa60e0848d784a6dd461da6.pngpackagecom.yyrookie.test;importjava.util.Date;public class ShallowCopy implementsCloneable {privateDate begin;publicDate getBegin(){return this.begin;

}public voidsetBegin(Date d){this.begin =d;

}publicObject clone(){

Object obj= null;try{

obj= super.clone();

}catch(CloneNotSupportedException ex){

ex.printStackTrace();

}returnobj;

}public static voidmain(String[] args) {

Date date= new Date(10000L);

ShallowCopy copy= newShallowCopy();

copy.setBegin(date);

ShallowCopy copy2=(ShallowCopy) copy.clone();

System.out.println(copy.getBegin()+ "\n"

+ copy2.getBegin() + "\n" +(copy==copy2));

date.setTime(100000000L);;

System.out.println(copy.getBegin()+ "\n"

+ copy2.getBegin() + "\n" +(copy==copy2));

}//Thu Jan 01 08:00:10 CST 1970//Thu Jan 01 08:00:10 CST 1970//false//Fri Jan 02 11:46:40 CST 1970//Fri Jan 02 11:46:40 CST 1970//false

}

69c5a8ac3fa60e0848d784a6dd461da6.png

相比深拷贝,拷贝对象的同时,又进行了对成员对象进行了深拷贝。

69c5a8ac3fa60e0848d784a6dd461da6.pngpackagecom.yyrookie.test;importjava.util.Date;public class DeepCopy implementsCloneable{privateDate begin;publicDate getBegin(){return this.begin;

}public voidsetBegin(Date d){this.begin =d;

}publicObject clone(){

DeepCopy obj= null;try{

obj= (DeepCopy)super.clone();

}catch(CloneNotSupportedException e){

e.printStackTrace();

}

obj.setBegin((Date)this.getBegin().clone());returnobj;

}public static voidmain(String[] args) {

Date date= new Date(10000L);

DeepCopy copy= newDeepCopy();

copy.setBegin(date);

DeepCopy copy2=(DeepCopy) copy.clone();

System.out.println(copy.getBegin()+ "\n"

+ copy2.getBegin() + "\n" +(copy==copy2));

date.setTime(100000000L);

System.out.println(copy.getBegin()+ "\n"

+ copy2.getBegin() + "\n" +(copy==copy2));

}//Thu Jan 01 08:00:10 CST 1970//Thu Jan 01 08:00:10 CST 1970//false//Fri Jan 02 11:46:40 CST 1970//Thu Jan 01 08:00:10 CST 1970//false

}

69c5a8ac3fa60e0848d784a6dd461da6.png

原文:http://www.cnblogs.com/yyrookie/p/3586169.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值