java笔记--关于克隆技术
关于克隆
--如果朋友您想转载本文章请注明转载地址"http://www.cnblogs.com/XHJT/p/3884817.html"谢谢--
1.假克隆
如:
ObjectA objA = new ObjectA();
ObjectB objB = objA;
(对于引用变量而言,使用"="将修改引用,而不是复制堆中的对象,
此时两个引用变量将指向同一个对象,因此,若是一个变量对其进行修改则会改变另外一个变量)
当修改objA时,objB也被修改,故称之为"假克隆"
2.浅克隆
当克隆对象时,需要使用clone()方法:
public Object clone() throws CloneNotSupportedException(默认情况下,该方法实现浅克隆)
由于该方法是受保护的方法,通常需要重写该方法并将访问权限改为public。
该方法将类中各个域进行复制,对于引用类型的域,这种操作会出现问题,故称之为"浅克隆"
提供克隆的类需要实现Cloneable接口,否则使用clone()方法时会抛出CloneNotSupportedException。
@Override
public ObjectA clone(){
ObjectA objA = null;
try{
objA = (ObjectA)super.clone();
}catch(CloneNotSupportedException e){
e.printStackTrace();
}
return objA;
}
注意:对于类中的域,如果只包含基本类型和不可变的引用类型,如String,或者对象在其生命周期内不会发生变化,则可以使用浅克隆来复制对象。
3.深克隆
当克隆对象时,需要使用clone()方法:
public Object clone() throws CloneNotSupportedException
(其中ObjectA类是ObjectB类中的一个属性)
@Override
public ObjectB clone(){
ObjectB objB = null;
try{
objB = (ObjectB)super.clone();
objB.objA = objA.clone();
}catch(CloneNotSupportedException e){
e.printStackTrace();
}
return objB;
}
注意:通常情况下,克隆对象时都需要使用深克隆。但是需要注意的是,如果引用类型中还有可变的引用类型域,
则该域也需要被进行克隆,如上面的ObjectA类如果增加一个X域,则该域也需要被克隆。
4.序列化实现深克隆
对于深克隆而言,如果有很多引用类型的域,那么重写clone()方法一次复制各个域是非常麻烦的,
如果引用类型的域也是由引用类型组成的,则应该考虑使用序列化的方式实现深克隆。
使用序列化写入完成再读出即可实现克隆,此种方法不用考虑引用类型的域,编写clone()方法相对简单,但是要求引用类型也实现Seralizable接口
(若是使用了API中的类且该类并没有实现Seralizable接口,则该域需要使用transient修饰)
ObjectB:
public class ObjectB implements Serializable{
……
@Override
public ObjectB clone(){
ObjectB objB = null;
ByteArrayOutputStream baos = new ByteArrayOutputStream();
try{
//将对象写入到字节数组中
ObjectOutputStream oos = new ObjectOutputStream(baos);
oos.writeObject(this);
oos.close();
}catch(IOException e){
e.printStackTrace();
}
ByteArrayInputStream bais = new ByteArrayInputStream(baos.toByteArray());
try{
//从字节数组中读取对象
ObjectInputStream ois = new ObjectInputStream(bais);
objB = (ObjectB)ois.readObject();
ois,close();
}catch(IOException e){
e.printStackTrace();
}
return objB;
}
}
对于任何序列化对象,都要求实现Seralizable接口,若是域中有引用类型,则要求该引用类型也实现Seralizable接口。
(效率比直接克隆各个引用类型域慢)
总结:
如果类的各个域是基本类型或不可变类型,则可以使用浅克隆,否则使用深克隆
如果类的域比较复杂,可以使用序列化的方式实现,否则应该使用复制域的方式实现深克隆。
java笔记--关于克隆技术的更多相关文章
- golang学习笔记17 爬虫技术路线图,python,java,nodejs,go语言,scrapy主流框架介绍
golang学习笔记17 爬虫技术路线图,python,java,nodejs,go语言,scrapy主流框架介绍 go语言爬虫框架:gocolly/colly,goquery,colly,chrom ...
- JAVA数据库编程(JDBC技术)-入门笔记
本菜鸟才介入Java,我现在不急着去看那些基本的语法或者一些Java里面的版本的特征或者是一些晋级的知识,因为有一点.Net的OOP编程思想,所以对于Java的这些语法以及什么的在用到的时候在去发现学 ...
- java笔记整理
Java 笔记整理 包含内容 Unix Java 基础, 数据库(Oracle jdbc Hibernate pl/sql), web, JSP, Struts, Ajax Spring, E ...
- Java实例 Part6:Java中的克隆
目录 Part6:Java中的克隆 Example01:Java对象的假克隆 Example02:Java对象的浅克隆 Example03:Java对象的深克隆 Example04:序列化与对象克隆 ...
- Effective Java笔记一 创建和销毁对象
Effective Java笔记一 创建和销毁对象 第1条 考虑用静态工厂方法代替构造器 第2条 遇到多个构造器参数时要考虑用构建器 第3条 用私有构造器或者枚举类型强化Singleton属性 第4条 ...
- Java中如何克隆集合——ArrayList和HashSet深拷贝
编程人员经常误用各个集合类提供的拷贝构造函数作为克隆List,Set,ArrayList,HashSet或者其他集合实现的方法.需要记住的是,Java集合的拷贝构造函数只提供浅拷贝而不是深拷贝,这意味 ...
- Java Web之JSP技术
JSP全称是Java Server Pages,它和servle技术一样,都是SUN公司定义的一种用于开发动态web资源的技术.JSP这门技术的最大的特点在于,写jsp就像在写html,但它相比htm ...
- Java Web之会话技术
客户端与服务器通信过程中,会产生一些数据.比如,A和B分别登陆了某宝购物网站,A买了一个Android手机,B买了一个iPhone手机,当结账时,web服务器需要分别对用户A和B的信息分别保存.根据J ...
- java笔记00-目录
--2013年7月26日17:49:59 学习java已久,趁最近有空,写一个总结: java笔记01-反射:
随机推荐
- display:inline-block的坑
一直用display:inline-block做某种导航栏还很爽,突然有一个柱状图的需求便也这么做了,于是成功被坑. 简简单单个需求,大致这样 只用几个li加上display:inline-block ...
- 手把手教你Linux服务器集群部署.net网站 - Linux系统安装和设置
在开源软件已成趋势化的今天,微软这‘老古董’也开始向开源方向发力,这对我们.NET开发者是极大的喜讯.而在开源软件中, Linux就是其中一个优秀的代表,几乎各行业和计算机有关的都有它的身影,其中一点 ...
- 扫描二维码下载安装apk的app
将apk文件放到服务器上,下载链接直接生成二维码,用微信扫描时不能直接下载.页面只是刷新一下. 想实现微信扫描下载apk的app客户端,需要把下载链接做到一个网页上, 将网页生成一个二维码. 直接下载 ...
- [AaronYang]C#人爱学不学[3]
本文章不适合入门,只适合有一定基础的人看.我更相信知识细节见高低,我是从4.0开始学的,终于有时间系统的学习C#5.0,是5.0中的知识,会特殊标记下.但写的内容也可能含有其他版本framework的 ...
- AngularJS - 服务简介
服务是AngularJS中非常重要的一个概念,虽然我们有了控制器,但考虑到其生命实在脆弱,我们需要用到服务. 起初用service时,我便把service和factory()理所当然地关联起来了. 确 ...
- FilenameFilter用法
使用FilenameFilter实现图片过滤,只要.gif,.jpg,.png文件. java 代码 public class ImageFilter implements FilenameFilte ...
- 转-JS之Window对象
一.说明:他是JS中最大的对象,它描述的是一个浏览器窗口,一般要引用他的属性和方法时,不需要用“Window.XXX”这种形式,而是直接使用“XXX”.一个框架页面也是一个窗口. 二.Window窗口 ...
- JavaScript事件冒泡简介及应用
一.什么是事件冒泡 在一个对象上触发某类事件(比如单击onclick事件),如果此对象定义了此事件的处理程序,那么此事件就会调用这个处理程序,如果没有定义此事 件处理程序或者事件返回true,那么这个 ...
- Yii2 实现修改密码功能
YII2对密码加密生成的结果是不同的,即用相同的初始密码在不同时间得到的加密结果不同,所以我们不能用常用的方法去验证密码是否正确(将密码加密后与数据库中的密码相比较).YII2有自己的加密以及密码验证 ...
- BZOJ1015 [JSOI2008]星球大战starwar
Description 很久以前,在一个遥远的星系,一个黑暗的帝国靠着它的超级武器统治者整个星系.某一天,凭着一个偶然的 机遇,一支反抗军摧毁了帝国的超级武器,并攻下了星系中几乎所有的星球.这些星球通 ...