详解Java中的clone方法 -- 原型模式
转自: http://blog.csdn.net/zhangjg_blog/article/details/18369201
Java中对象的创建
复制对象 or 复制引用
- Person p = new Person(23, "zhang");
- Person p1 = p;
- System.out.println(p);
- System.out.println(p1);
当Person p1 = p;执行之后, 是创建了一个新的对象吗? 首先看打印结果:
com.pansoft.zhangjg.testclone.Person@2f9ee1ac
- Person p = new Person(23, "zhang");
- Person p1 = (Person) p.clone();
- System.out.println(p);
- System.out.println(p1);
从打印结果可以看出,两个对象的地址是不同的,也就是说创建了新的对象, 而不是把原对象的地址赋给了一个新的引用变量:
com.pansoft.zhangjg.testclone.Person@67f1fba0
深拷贝 or 浅拷贝
- public class Person implements Cloneable{
- private int age ;
- private String name;
- public Person(int age, String name) {
- this.age = age;
- this.name = name;
- }
- public Person() {}
- public int getAge() {
- return age;
- }
- public String getName() {
- return name;
- }
- @Override
- protected Object clone() throws CloneNotSupportedException {
- return (Person)super.clone();
- }
- }
- Person p = new Person(23, "zhang");
- Person p1 = (Person) p.clone();
- String result = p.getName() == p1.getName()
- ? "clone是浅拷贝的" : "clone是深拷贝的";
- System.out.println(result);
覆盖Object中的clone方法, 实现深拷贝
- static class Body implements Cloneable{
- public Head head;
- public Body() {}
- public Body(Head head) {this.head = head;}
- @Override
- protected Object clone() throws CloneNotSupportedException {
- return super.clone();
- }
- }
- static class Head /*implements Cloneable*/{
- public Face face;
- public Head() {}
- public Head(Face face){this.face = face;}
- }
- public static void main(String[] args) throws CloneNotSupportedException {
- Body body = new Body(new Head());
- Body body1 = (Body) body.clone();
- System.out.println("body == body1 : " + (body == body1) );
- System.out.println("body.head == body1.head : " + (body.head == body1.head));
- }
在以上代码中, 有两个主要的类, 分别为Body和Face, 在Body类中, 组合了一个Face对象。当对Body对象进行clone时, 它组合的Face对象只进行浅拷贝。打印结果可以验证该结论:
body.head == body1.head : true
- static class Body implements Cloneable{
- public Head head;
- public Body() {}
- public Body(Head head) {this.head = head;}
- @Override
- protected Object clone() throws CloneNotSupportedException {
- Body newBody = (Body) super.clone();
- newBody.head = (Head) head.clone();
- return newBody;
- }
- }
- static class Head implements Cloneable{
- public Face face;
- public Head() {}
- public Head(Face face){this.face = face;}
- @Override
- protected Object clone() throws CloneNotSupportedException {
- return super.clone();
- }
- }
- public static void main(String[] args) throws CloneNotSupportedException {
- Body body = new Body(new Head());
- Body body1 = (Body) body.clone();
- System.out.println("body == body1 : " + (body == body1) );
- System.out.println("body.head == body1.head : " + (body.head == body1.head));
- }
打印结果为:
body.head == body1.head : false
真的是深拷贝吗
- static class Body implements Cloneable{
- public Head head;
- public Body() {}
- public Body(Head head) {this.head = head;}
- @Override
- protected Object clone() throws CloneNotSupportedException {
- Body newBody = (Body) super.clone();
- newBody.head = (Head) head.clone();
- return newBody;
- }
- }
- static class Head implements Cloneable{
- public Face face;
- public Head() {}
- public Head(Face face){this.face = face;}
- @Override
- protected Object clone() throws CloneNotSupportedException {
- return super.clone();
- }
- }
- static class Face{}
- public static void main(String[] args) throws CloneNotSupportedException {
- Body body = new Body(new Head(new Face()));
- Body body1 = (Body) body.clone();
- System.out.println("body == body1 : " + (body == body1) );
- System.out.println("body.head == body1.head : " + (body.head == body1.head));
- System.out.println("body.head.face == body1.head.face : " + (body.head.face == body1.head.face));
- }
打印结果为:
body.head == body1.head : false
body.head.face == body1.head.face : true
如何进行彻底的深拷贝
- static class Head implements Cloneable{
- public Face face;
- public Head() {}
- public Head(Face face){this.face = face;}
- @Override
- protected Object clone() throws CloneNotSupportedException {
- //return super.clone();
- Head newHead = (Head) super.clone();
- newHead.face = (Face) this.face.clone();
- return newHead;
- }
- }
- static class Face implements Cloneable{
- @Override
- protected Object clone() throws CloneNotSupportedException {
- return super.clone();
- }
- }
再次运行上面的示例,得到的运行结果如下:
body.head == body1.head : false
body.head.face == body1.head.face : false
写在最后
详解Java中的clone方法 -- 原型模式的更多相关文章
- 详解Java中的clone方法 -- 原型模式 及源码
http://www.cnblogs.com/cq-home/p/6431426.html http://blog.csdn.net/zhangjg_blog/article/details/1836 ...
- 详解Java中的clone方法
详解Java中的clone方法 参考:http://blog.csdn.net/zhangjg_blog/article/details/18369201/ 所谓的复制对象,首先要分配一个和源对象同样 ...
- 详解Java中的clone方法:原型模式
转:http://developer.51cto.com/art/201506/478985.htm clone顾名思义就是复制, 在Java语言中, clone方法被对象调用,所以会复制对象.所谓的 ...
- 详解 Java 中的三种代理模式
代理模式 代理(Proxy)是一种设计模式,提供了对目标对象另外的访问方式;即通过代理对象访问目标对象.这样做的好处是:可以在目标对象实现的基础上,增强额外的功能操作,即扩展目标对象的功能. 这里使用 ...
- 实例详解Java中如何对方法进行调用
原文源自http://www.jb51.net/article/73827.htm 方法调用Java支持两种调用方法的方式,根据方法是否返回值来选择. 当程序调用一个方法时,程序的控制权交给了被调用的 ...
- 转:Java中的Clone()方法详解
Java中对象的创建 clone顾名思义就是复制, 在Java语言中, clone方法被对象调用,所以会复制对象.所谓的复制对象,首先要分配一个和源对象同样大小的空间,在这个空间中创建一个新的对象.那 ...
- Java中的clone方法-理解浅拷贝和深拷贝
最近学到Java虚拟机的相关知识,更加能理解clone方法的机制了 java中的我们常常需要复制的类型有三种: 1:8种基本类型,如int,long,float等: 2:复合数据类型(数组): 3:对 ...
- java中的clone方法
Java中对象的创建 clone顾名思义就是复制, 在Java语言中, clone方法被对象调用,所以会复制对象.所谓的复制对象,首先要分配一个和源对象同样大小的空间,在这个空间中创建一个新的对象.那 ...
- JAVA中的clone方法剖析
原文出自:http://blog.csdn.net/shootyou/article/details/3945221 java中也有这么一个概念,它可以让我们很方便的"制造"出一个 ...
随机推荐
- iOS各种问题处理
本文转载至:http://www.cnblogs.com/ygm900/category/436923.html 推荐初学者前去学习. mac 拷贝文件时报错 8060 解决方案 摘要: 解决 ...
- Erstudio8.0怎么用?Erstudio8.0汉化版详细使用教程
Erstudio8.0使用教程 打开ERstudio,点击新建出现如图对话框: 选择第一个,表示创建一个新的关系型 数据库模型 这里提一点数据库模型分为relational(关系)和dimension ...
- PHPStorm自动压缩YUI Compressor配置
File---Settings...---Tools---File Watchers 点击右边加号,添加: 在弹出窗中 主要是Program的内容,点击后面的省略点,默认目录下回出现yuicompre ...
- redhad linux 7 安装ftp服务
1. 查看有没有安装 rpm -qa|grep vsftpd 2.安装vsftp yum install vsftpd -y 3. 启动vsftp /sbin/service vsftpd start ...
- 六 Android Studio打包Eegret App (解决开机黑屏问题)
因为android studio中的SplashActivity并没有什么卵用,只是开机1s显示开机画面,1s后面还是黑屏. 在主文件中加入以下代码,就是开始游戏时显示一个居中填满屏幕的图片,游戏加载 ...
- Fragment,仿QQ空间
转载请注明出处:http://blog.csdn.net/yangyu20121224/article/details/9023451 在今天的这篇文章当中,我依然会以实战加理论结合 ...
- web测试点--摘录
转载地址:Web测试到底是在测什么 一.输入框 1.字符型输入框: (1)字符型输入框:英文全角.英文半角.数字.空或者空格.特殊字符“~!@#¥%……&*?[]{}”特别要注意单引号和&am ...
- Linux C 获取 文件的大小
通过Linux C库函数来获取文件的大小 #include <unistd.h> #include <sys/types.h> #include <sys/stat.h& ...
- apt-get 报 The following signatures were invalid: KEYEXPIRED 错误
apt-get 原理: 参考:https://blog.csdn.net/a13526758473/article/details/79247478 apt对它所管理的每一个程序包都有一对公钥和私钥, ...
- LInux中的物理内存管理
2017-02-23 一.伙伴系统 LInux下用伙伴系统管理物理内存页,伙伴系统得益于其良好的算法,一定程度上可以避免外部碎片为何这么说?先回顾下Linux下虚拟地址空间的分布. 在X86架构下,系 ...