java Clone之深浅拷贝
要点:
1、浅度拷贝可以不实现Cloneable接口(自动使用Object.clone)或者不重写Cloneable的clone方法。
2、要被深度拷贝的类必须实现Cloneable接口并重写clone方法。
3、如果需要能被深度拷贝则需要在父一级对所有的非基本类型的子元素调用clone方法。
看例子:
/**
* 浅度clone的对象(浅拷贝)
*
* @author yzl
*/
public class ShallowCloneFavorite {
private String name;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
/**
* 深度clone(深拷贝)
*
* @author yzl
*/
public class DepthCloneFavorite implements Cloneable{
private String name; public String getName() {
return name;
} public void setName(String name) {
this.name = name;
} /* (non-Javadoc)
* @see java.lang.Object#clone()
*/
@Override
protected DepthCloneFavorite clone() throws CloneNotSupportedException {
return (DepthCloneFavorite)super.clone();
}
}
聚合类:
import java.util.ArrayList;
import java.util.List; /**
* JAVA深浅Clone测试集成类
*
* @author yzl
*/
public class Person implements Cloneable {
//基础类型直接值拷贝
private String type;
//未实现Cloneable接口的浅拷贝对象
private ShallowCloneFavorite scf;
//实现了Cloneable接口的可以进行深拷贝的对象
private DepthCloneFavorite dcf;
//可以深度Clone的list
private List<DepthCloneFavorite> dcfList; public String getType() {
return type;
}
public void setType(String type) {
this.type = type;
}
public ShallowCloneFavorite getScf() {
return scf;
}
public void setScf(ShallowCloneFavorite scf) {
this.scf = scf;
}
public DepthCloneFavorite getDcf() {
return dcf;
}
public void setDcf(DepthCloneFavorite dcf) {
this.dcf = dcf;
} public List<DepthCloneFavorite> getDcfList() {
return dcfList;
}
public void setDcfList(List<DepthCloneFavorite> dcfList) {
this.dcfList = dcfList;
} @Override
protected Person clone() throws CloneNotSupportedException {
Person p = (Person)super.clone();
//深拷贝Person的成员变量
p.setDcf(dcf.clone());
//深拷贝list
if(null!=dcfList && !dcfList.isEmpty()){
List<DepthCloneFavorite> copyList = new ArrayList<DepthCloneFavorite>(dcfList.size());
for(DepthCloneFavorite obj : dcfList){
copyList.add(obj.clone());
}
p.setDcfList(copyList);
}
return p;
} /**
*
* 显示对象里的数据
*
* @see [相关类/方法](可选)
* @since [产品/模块版本](可选)
*/
public void display(){
System.out.println("------------------");
System.out.println("type: " + type);
System.out.println("ShallowCloneFavorite.name: " + this.scf.getName());
System.out.println("DepthCloneFavorite.name: " + dcf.getName());
if(null!=dcfList && !dcfList.isEmpty()){
for(int i=0; i<dcfList.size(); i++){
System.out.println("DepthCloneFavoriteList["+ (i+1) +"].name: " + dcfList.get(i).getName());
}
}
System.out.println("------------------");
}
}
测试类:
import java.util.ArrayList;
import java.util.List; /**
* JAVA clone之深浅拷贝测试
*
* @author yzl
*/
public class Test {
public static void main(String[] args) throws Exception {
Person p = getBasePerson();
p.display(); Person p1 = p.clone();
p1.setType("girl");
p1.getDcf().setName("dancing");
p1.getScf().setName("singing");
p1.getDcfList().get(0).setName("yoga");
p1.display(); p.display();
} private static Person getBasePerson(){
ShallowCloneFavorite scf = new ShallowCloneFavorite();
scf.setName("basketball"); DepthCloneFavorite dcf = new DepthCloneFavorite();
dcf.setName("football"); DepthCloneFavorite dcf2 = new DepthCloneFavorite();
dcf2.setName("baseball");
List<DepthCloneFavorite> dcfList = new ArrayList<DepthCloneFavorite>(1);
dcfList.add(dcf2); Person p = new Person();
p.setType("boy");
p.setDcf(dcf);
p.setDcfList(dcfList);
p.setScf(scf); return p;
}
}
运行结果如下:
------------------
type: boy
ShallowCloneFavorite.name: basketball(浅度拷贝,值变化了)
DepthCloneFavorite.name: football
DepthCloneFavoriteList[1].name: baseball
------------------
------------------
type: girl
ShallowCloneFavorite.name: singing
DepthCloneFavorite.name: dancing
DepthCloneFavoriteList[1].name: yoga
------------------
------------------
type: boy
ShallowCloneFavorite.name: singing(浅度拷贝,值变化了)
DepthCloneFavorite.name: football
DepthCloneFavoriteList[1].name: baseball
------------------
java Clone之深浅拷贝的更多相关文章
- Java中的深浅拷贝问题,你清楚吗?
一.前言 拷贝这个词想必大家都很熟悉,在工作中经常需要拷贝一份文件作为副本.拷贝的好处也很明显,相较于新建来说,可以节省很大的工作量.在Java中,同样存在拷贝这个概念,拷贝的意义也是可以节省创建对象 ...
- 关于Java的Object.clone()方法与对象的深浅拷贝
文章同步更新在个人博客:关于Java的Object.clone()方法与对象的深浅拷贝 引言 在某些场景中,我们需要获取到一个对象的拷贝用于某些处理.这时候就可以用到Java中的Object.clon ...
- java提高(15)---java深浅拷贝
#java深浅拷贝 一.前言 为什么会有深浅拷贝这个概念? 我觉得主要跟JVM内存分配有关,对于基本数据类型,只存在栈内存,所以它的拷贝不存在深浅拷贝这个概念.而对于对象而言,一个对象的创建会在内存中 ...
- 关于Java中的HashMap的深浅拷贝的测试与几点思考
0.前言 工作忙起来后,许久不看算法,竟然DFA敏感词算法都要看好一阵才能理解...真是和三阶魔方还原手法一样,田园将芜,非常可惜啊. 在DFA算法中,第一步是需要理解它的数据结构,在此基础上,涉及到 ...
- C++/C#中堆栈、对象内存模型、深浅拷贝、Array.Clone方法
转载自:http://blog.csdn.net/jarvischu/article/details/6425534 目录 1. C++/C#中对象内存模型................. ...
- 为什么阿里Java手册推荐慎用 Object 的 clone 方法来拷贝对象
图片若无法显示,可至掘金查看https://juejin.im/post/5d425230f265da039519d248 前言 在阿里Java开发手册中,有这么一条建议:慎用 Object 的 cl ...
- 什么是java的深浅拷贝?
什么是java的深浅拷贝? 浅拷贝 就是很肤浅的拷贝,只拷贝了别人的地址.没有拷贝地址里面的值.地址里面的值改变后,就都改变了. 深拷贝 就是很深入的拷贝,深入到核心的拷贝,拷贝了别人地址里面的值,别 ...
- 巨蟒python全栈开发-第7天 基本数据类型补充&深浅拷贝
1.基本数据类型补充 2.深浅拷贝 DAY7-基本数据类型(基本数据类型补充&深浅拷贝) 本节主要内容: 1.补充基础数据类型 (1)join方法 (2)split方法 (3)列表不能在循环时 ...
- 【 js 基础 】 深浅拷贝
underscore的源码中,有很多地方用到了 Array.prototype.slice() 方法,但是并没有传参,实际上只是为了返回数组的副本,例如 underscore 中 clone 的方法: ...
随机推荐
- 《精通Matlab神经网络》例10-16的新写法
<精通Matlab神经网络>书中示例10-16,在创建BP网络时,原来的写法是: net = newff(minmax(alphabet),[S1 S2],{'logsig' 'logsi ...
- mysql 怎么查询出,分组后的总条数。。。也就是有多少组数。。。。怎么写
SELECT COUNT(*) AS 多少组数FROM( SELECT id FROM 表 GROUP BY id) subQuery;Mysql,有一个表含有以下字段,uid 发帖人id,title ...
- java获取classpath文件路径空格转变成了转义字符%20的问题
java获取classpath文件路径空格转变成了转义字符%20的问题 这个问题很纠结,服务器的文件路径带有空格,空格被转化是%20了,悲剧就出现了 下面展示一段代码String path = get ...
- 从源代码分析Android-Universal-Image-Loader图片下载技巧
在手机上尤其需要考虑网络对图片下载的影响,常见的情况是在2G网络.在3G网络需要不同的下载策略,也就是说在慢速网络与快速网络中下载需要考虑不同的策略.一种常见的策略就是Android客户端和服务端相配 ...
- Java正则表达式的应用
在很多种情况下,我们都必须对字符串进行匹配,以便判断字符串的格式是否符合要求,对字符串中的内容进行提取.比如,我要从一段话aabdfe中,判断这段话是否有包含ab这个词,那么如果用if-else来判断 ...
- EditPlus不能着色显示SQl语句的问题
说明:今天重装了系统后,从网上安装下载了一个EditPlus阅读代码,发现sql语句是灰色的,不和以前的带有颜色的看着美观了,顿时心里别扭了起来.以为下错了版本,可是换了好几个,都是这样,网上查了一下 ...
- 关于解决keil4和mdk共存后51不能使用go to definition Of 'XXXXXX'问题
自己安装keil4和mdk共存后,(我是先安装的keil 后安装的 MDK),在51单片机工程里不能使用go to definition Of 'XXXXXX'问题, 类似的如图 已经困扰了好长时间, ...
- SqlServer 查看事务锁及执行语句
一.查看当前锁定的事务 ,) ,用户机器名称,) ,是否被锁住),blocked) ,数据库名称,),cmd 命令,waittype as 等待类型 ,last_batch 最后批处理时间,open_ ...
- 通过weburl 启动windows程序
1. 注册表修改 建立一个reg文件 执行导入 以RunLocal协议为例子 Windows Registry Editor Version 5.00 [HKEY_CLASSES_ROOT\RunL ...
- 使用 nc (Netcat) 建立傳送資料的 socket server
原文:http://blog.longwin.com.tw/2012/02/nc-data-send-socket-server-2012/ 於 Debian / Ubuntu Linux 想要透過 ...