Java-克隆
2016-05-25 16:11
316 查看
假克隆
1测试代码
2输出结果
3结果分析
浅克隆
1测试代码
2输出结果
3结果分析
深克隆
测试代码
输出结果
结果分析
总结
{
“boss”: {
“name”: “头”
},
“name”: “小明”
}
//这是假克隆:
{
“boss”: {
“name”: “头”
},
“name”: “小明”
}
需要Bean实现Cloneable接口:
{
“boss”: {
“name”: “头”
},
“name”: “张三”
}
//这是浅克隆:
{
“boss”: {
“name”: “头”
},
“name”: “小明”
}
{
“boss”: {
“name”: “老大”
},
“name”: “张三”
}
//这是深克隆:
{
“boss”: {
“name”: “头”
},
“name”: “小明”
}
clone的深克隆其实就是序列化和反序列化,这里有很多种选择,Serializable、Parcelable、JSON等均可
clone方法不同于new方法,不会执行构造方法
参考目录:
1. 详解Java中的clone方法 – 原型模式
1测试代码
2输出结果
3结果分析
浅克隆
1测试代码
2输出结果
3结果分析
深克隆
测试代码
输出结果
结果分析
总结
1.假克隆
1.1测试代码
/** * 假克隆 * <p> * 只复制了对象,没有复制对象的引用 */ private static void testFakeClone() { //源对象 Bean bean = new Bean("张三", new Boss("老大")); //这是克隆对象 Bean clone = bean; clone.setName("小明"); clone.getBoss().setName("头"); System.out.println("这是原始数据:"); System.out.println(JSON.toJSONString(bean)); System.out.println("这是假克隆:"); System.out.println(JSON.toJSONString(clone)); }
1.2.输出结果:
//这是原始数据:{
“boss”: {
“name”: “头”
},
“name”: “小明”
}
//这是假克隆:
{
“boss”: {
“name”: “头”
},
“name”: “小明”
}
1.3.结果分析:
这里,我们修改了克隆对象的属性之后,源对象的属性也同样变了,关系如图所示(图是盗来的,不要纠结于名称):2.浅克隆
2.1.测试代码:
/** * 浅克隆 * <p> * 既复制了对象,也复制了对象的引用 * 但是如果引用还存在引用,而更深层的引用如果没有实现cloneable接口,就还是会指向源对象 */ private static void testShallowClone() { //源对象 Bean bean = new Bean("张三", new Boss("老大")); //这是克隆对象 Bean clone = bean.clone(); clone.setName("小明"); clone.getBoss().setName("头"); System.out.println("这是原始数据:"); System.out.println(JSON.toJSONString(bean)); System.out.println("这是浅克隆:"); System.out.println(JSON.toJSONString(clone)); }
需要Bean实现Cloneable接口:
/** * 被克隆对象 * <p> */ public static class Bean implements Cloneable { private String name; private Boss boss; public Bean() { } public Bean(String name, Boss boss) { this.name = name; this.boss = boss; } public String getName() { return name; } public void setName(String name) { this.name = name; } public Boss getBoss() { return boss; } public void setBoss(Boss boss) { this.boss = boss; } @Override protected Bean clone() { Bean clone = null; try { clone = (Bean) super.clone(); } catch (CloneNotSupportedException e) { throw new RuntimeException(e); } return clone; } }
2.2.输出结果:
//这是原始数据:{
“boss”: {
“name”: “头”
},
“name”: “张三”
}
//这是浅克隆:
{
“boss”: {
“name”: “头”
},
“name”: “小明”
}
2.3.结果分析:
这里,我们修改了克隆对象的属性之后,源对象的name属性没有变,但是更深的引用boss却变了,说明此时源对象和克隆对象所引用的boss对象,其实还是同一个,关系如图所示(图是盗来的,不要纠结于名称):深克隆
测试代码:
/** * 深克隆 * <p> * 将对象序列化,再反序列化生成一个新对象即可 * Serializable、Parcelable、JSON等均可 */ private static void testDeepClone() { //源对象 Bean bean = new Bean("张三", new Boss("老大")); //这是克隆对象 String json = JSON.toJSONString(bean); Bean clone = JSON.parseObject(json, Bean.class); clone.setName("小明"); clone.getBoss().setName("头"); System.out.println("这是原始数据:"); System.out.println(JSON.toJSONString(bean)); System.out.println("这是深克隆:"); System.out.println(JSON.toJSONString(clone)); }
输出结果:
//这是原始数据:{
“boss”: {
“name”: “老大”
},
“name”: “张三”
}
//这是深克隆:
{
“boss”: {
“name”: “头”
},
“name”: “小明”
}
结果分析:
总结:
clone在平时项目中虽然用的不多,但是,区分深克隆和浅克隆却可以帮助我们理解java的内存结构clone的深克隆其实就是序列化和反序列化,这里有很多种选择,Serializable、Parcelable、JSON等均可
clone方法不同于new方法,不会执行构造方法
参考目录:
1. 详解Java中的clone方法 – 原型模式
相关文章推荐
- 设计模式第一节:类图
- SpringMVC中使用@RequestBody,@ResponseBody注解实现Java对象和XML/JSON数据自动转换(下)
- springmvc 4.X 搭建
- Dubbo与Zookeeper、SpringMVC整合和使用(负载均衡、容错)
- Spring Annotation 详解
- SpringMVC中使用@RequestBody,@ResponseBody注解实现Java对象和XML/JSON数据自动转换(上)
- Java多态 转型
- 同步阻塞式IO(BIO)--学习笔记
- Java注解
- Spring @transactional annotation 事务使用详解
- spring的annotation-driven配置事务管理器详解
- Java-String类的常用方法总结
- Java基础学习
- java if后面要加大括号
- Java中的事件处理与异常处理机制-解析
- Java语言中的取整运算
- Android Studio或Eclipse配置百度地图详解教程
- Java编码字符串,解码字符串,取得文件大小,读文件内容
- Java Web项目中验证码功能的制作攻略
- 类 java.awt.event.ActionEvent 等的使用