关于克隆

--如果朋友您想转载本文章请注明转载地址"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笔记--关于克隆技术的更多相关文章

  1. golang学习笔记17 爬虫技术路线图,python,java,nodejs,go语言,scrapy主流框架介绍

    golang学习笔记17 爬虫技术路线图,python,java,nodejs,go语言,scrapy主流框架介绍 go语言爬虫框架:gocolly/colly,goquery,colly,chrom ...

  2. JAVA数据库编程(JDBC技术)-入门笔记

    本菜鸟才介入Java,我现在不急着去看那些基本的语法或者一些Java里面的版本的特征或者是一些晋级的知识,因为有一点.Net的OOP编程思想,所以对于Java的这些语法以及什么的在用到的时候在去发现学 ...

  3. java笔记整理

    Java 笔记整理 包含内容     Unix Java 基础, 数据库(Oracle jdbc Hibernate pl/sql), web, JSP, Struts, Ajax Spring, E ...

  4. Java实例 Part6:Java中的克隆

    目录 Part6:Java中的克隆 Example01:Java对象的假克隆 Example02:Java对象的浅克隆 Example03:Java对象的深克隆 Example04:序列化与对象克隆 ...

  5. Effective Java笔记一 创建和销毁对象

    Effective Java笔记一 创建和销毁对象 第1条 考虑用静态工厂方法代替构造器 第2条 遇到多个构造器参数时要考虑用构建器 第3条 用私有构造器或者枚举类型强化Singleton属性 第4条 ...

  6. Java中如何克隆集合——ArrayList和HashSet深拷贝

    编程人员经常误用各个集合类提供的拷贝构造函数作为克隆List,Set,ArrayList,HashSet或者其他集合实现的方法.需要记住的是,Java集合的拷贝构造函数只提供浅拷贝而不是深拷贝,这意味 ...

  7. Java Web之JSP技术

    JSP全称是Java Server Pages,它和servle技术一样,都是SUN公司定义的一种用于开发动态web资源的技术.JSP这门技术的最大的特点在于,写jsp就像在写html,但它相比htm ...

  8. Java Web之会话技术

    客户端与服务器通信过程中,会产生一些数据.比如,A和B分别登陆了某宝购物网站,A买了一个Android手机,B买了一个iPhone手机,当结账时,web服务器需要分别对用户A和B的信息分别保存.根据J ...

  9. java笔记00-目录

    --2013年7月26日17:49:59 学习java已久,趁最近有空,写一个总结: java笔记01-反射:

随机推荐

  1. 如何优雅的写一篇安利文-以Sugar ORM为例

    前言 我最近喜欢把写的十分优美的技术文章叫做安利文.首先,文章必须是原创而非软广:其次,阅读之后不仅能快速吸纳技术要点并入门开发,还能感同身受的体会作者热情洋溢的赞美和急于分享心得体验的心情,让人感觉 ...

  2. 细说 Web API参数绑定和模型绑定

    今天跟大家分享下在Asp.NET Web API中Controller是如何解析从客户端传递过来的数据,然后赋值给Controller的参数的,也就是参数绑定和模型绑定. Web API参数绑定就是简 ...

  3. Unity3D独立游戏开发日记(二):摆放建筑物

    在沙盒游戏里,能自由建造是很重要的特点,比如说风靡全球的<我的世界>,用一个个方块就能搭建出规模宏大的世界.甚至有偏激的人说,没有自由建造,就不是一个真正的沙盒游戏.的确,沙盒游戏的魅力有 ...

  4. [USACO2002][poj1945]Power Hungry Cows(启发式搜索)

    Power Hungry CowsTime Limit: 1000MS Memory Limit: 30000K Total Submissions: 4570 Accepted: 1120 Desc ...

  5. 安装及破解IntelliJ IDEA15

    1. 下载安装包 进入 JetBrains 官网,http://www.jetbrains.com/idea/download/#tabs_1=windows, 从Ultimate下载企业版 Inte ...

  6. python 逐行读取文件的三种方法

    方法一: 复制代码代码如下: f = open("foo.txt")             # 返回一个文件对象  line = f.readline()             ...

  7. java连接sql server2000/2005

    接触Java或者JSP,难免会使用到数据库SQL Server 2000/2005(我使用2005标准版[9.0.3054]测试),经过自己的搜索和研究,使用JDBC连接SQL Server成功,特此 ...

  8. openvpn的介绍和搭建过程

    本文摘自:http://www.linuxidc.com/Linux/2012-01/51702.htm,在这只是为了做个笔记使用

  9. codevs 1378选课 树形DP

    #include<cstdio> #include<cstring> #include<algorithm> using namespace std; ],tr[] ...

  10. hdu2072 字典树

    这题印象深刻,我刚接触acm时,以为这题是水题(因为是中文,又短),一直没做出.现再想想也是.可能也是我以前字符串掌握不好: 这题其实也可以用stl里的map写.这里我用字典树写的.其实这题算简单题了 ...