世界热点评!java编程中的对象与引用的区别 java clone方法使用详解
Java语言的一个优点就是取消了指针的概念,但也导致了许多程序员在编程中常常忽略了对象与引用的区别,特别是先学c、c++后学java的程序员。并且由于Java不能通过简单的赋值来解决对象复制的问题,在开发过程中,也常常要要应用clone()方法来复制对象。比如函数参数类型是自定义的类时,此时便是引用传递而不是值传递。以下是一个小例子:
1 public classA {2 publicString name;3 }4 public classtestClone {5 public voidchangeA(A a){6 a.name="b";7 }8 public void changInt(inti){9 i=i*2+100;10 }11
(相关资料图)
12 /**
13 *@paramargs14 */
15 public static voidmain(String[] args) {16 //TODO Auto-generated method stub
17 testClone test=newtestClone();18 A a=newA();19 a.name="a";20 System.out.println("before change : a.name="+a.name);21 test.changeA(a);22 System.out.println("after change : a.name="+a.name);23 int i=1;24 System.out.println("before change : i="+i);25 test.changInt(i);26 System.out.println("after change : i="+i);27 }28
29 }
此时输出的结果是:
before change : a.name=a
after change : a.name=b
before change : i=1
after change : i=1
从这个例子知道Java对对象和基本的数据类型的处理是不一样的。在Java中用对象的作为入口参数的传递则缺省为"引用传递",也就是说仅仅传递了对象的一个"引用",这个"引用"的概念同C语言中的指针引用是一样的。当函数体内部对输入变量改变时,实质上就是在对这个对象的直接操作。
除了在函数传值的时候是"引用传递",在任何用"="向对象变量赋值的时候都是"引用传递",如:
1 A a1=newA();2 A a2=newA();3 a1.name="a1";4 a2=a1;5 a2.name="a2";6 System.out.println("a1.name="+a1.name);7 System.out.println("a2.name="+a2.name)
此时输出的结果是:
a1.name=a2
a2.name=a2
如果我们要用a2保存a1对象的数据,但又不希望a2对象数据被改变时不影响到a1。实现clone()方法是其一种最简单,也是最高效的手段。
下面我们来实现A的clone方法
1 public class A implementsCloneable2 {3 publicString name;4
5 publicObject clone()6 {7 A o = null;8 try
9 {10 o = (A) super.clone();11 } catch(CloneNotSupportedException e)12 {13 e.printStackTrace();14 }15 returno;16 }17 }
首先要实现Cloneable接口,然后在重载clone方法,最后在clone()方法中调用了super.clone(),这也意味着无论clone类的继承结构是什么样的,super.clone()直接或间接调用了java.lang.Object类的clone()方法。
1 A a1 = newA();2 A a2 = newA();3 a1.name = "a1";4 a2 =(A)a1.clone();5 a2.name = "a2";6 System.out.println("a1.name=" +a1.name);7 System.out.println("a2.name=" + a2.name);
此时输出的结果是:
a1.name=a1
a2.name=a2
当Class A成员变量类型是java的基本类型时(外加String类型),只要实现如上简单的clone(称影子clone)就可以。但是如果Class A成员变量是数组或复杂类型时,就必须实现深度clone。
1 public class A implementsCloneable2 {3 publicString name[];4
5 publicA()6 {7 name = new String[2];8 }9
10 publicObject clone()11 {12 A o = null;13 try
14 {15 o = (A) super.clone();16 } catch(CloneNotSupportedException e)17 {18 e.printStackTrace();19 }20 returno;21 }22 }
测试代码
1 A a1=newA();2 A a2=newA();3 a1.name[0]="a";4 a1.name[1]="1";5 a2=(A)a1.clone();6 a2.name[0]="b";7 a2.name[1]="1";8 System.out.println("a1.name="+a1.name);9 System.out.println("a1.name="+a1.name[0]+a1.name[1]);10 System.out.println("a2.name="+a2.name);11 System.out.println("a2.name="+a2.name[0]+a2.name[1]);
输出结果:
a1.name=[Ljava.lang.String;@757aef
a1.name=b1
a2.name=[Ljava.lang.String;@757aef
a2.name=b1
看到了吧,a1.name,a2.name的hash值都是@757aef,也就是说影子clone对name数组只是clone他们的地址!解决该办法是进行深度clone。
1 publicObject clone()2 {3 A o = null;4 try
5 {6 o = (A) super.clone();7 } catch(CloneNotSupportedException e)8 {9 e.printStackTrace();10 }11 o.name = new String[2];//其实也很简单^_^
12 returno;13 }
此时输出结果是:
a1.name=[Ljava.lang.String;@757aef
a1.name=a1
a2.name=[Ljava.lang.String;@d9f9c3
a2.name=b1
需要注意的是Class A存在更为复杂的成员变量时,如Vector等存储对象地址的容器时,就必须clone彻底。
1 public class A implementsCloneable {2 publicString name[];3 public VectorclaB;4
5 publicA(){6 name=new String[2];7 claB=new Vector();8 }9
10 publicObject clone() {11 A o = null;12 try{13 o = (A) super.clone();14 } catch(CloneNotSupportedException e) {15 e.printStackTrace();16 }17 o.name=new String[2];//深度clone
18 o.claB=new Vector();//将clone进行到底
19 for(int i=0;i
21 o.claB.add(temp);22 }23 returno;24 }25 }
标签:
相关推荐:
最新新闻:
- 苹果手机为什么充不进电?苹果手机充电充不进去电的原因及解决方法-每日动态
- 熔断机制什么意思?美股23年来首次启动熔断机制 每日信息
- 三星e728报价是多少?三星首款天线折叠手机E728评测-环球消息
- Android音频开发及录音文件的配置
- 当前热议!【管理-固件升级】从DD-WRT固件刷到Tomato的升级方案
- 可以搜附近人的交友软件有哪些?有哪些靠谱的交友软件?
- WEB服务器和cookie的区别在哪里?cookie和session的区别详解-今头条
- 如何查询appInfo、appName?appInfo查询方法_当前关注
- Windows、Mac、Unix、Linux什么是iOS?-报道
- 世界观天下!GIS开发Georver:共享地理空间数据的开源服务器
- 当前短讯!cf连接服务器连接失败怎么办?官方解决方法
- SP2的系统怎么操作?如何使用SP2的系统文件?
- dv机哪个好?索尼FD-AX100E热门款型推荐
- 统一目录是如何工作的?企业实现统一身份认证的作用和好处有哪些?
- 如何使用ZEGOExpressSDK实现多人语音通话?详情介绍:当前通讯
- 热文:酷我音乐盒有什么特点?酷我音乐盒特点介绍
- Android直播新思路:4.1Android推流到服务器:要闻速递
- 如何修改支付宝绑定的手机号码?支付宝绑定的手机号码如何修改? 简讯
- QQ.COM二级域名大全 腾讯旗下产品大全
- 什么是电竞?阿里电竞平台功能特点介绍-天天微速讯
- 每日消息!泛域名证书不起作用?主机绑定多个域名就可以了
- 当前看点!cad怎么导出jpg图片格式?cad导出jpg图片格式的方法
- 带你走一遍自定义View之旅——效果图
- 世界热点评!java编程中的对象与引用的区别 java clone方法使用详解
- 天天观点:iOS14/iPadOS14正式发布 支持升级至苹果机型
- 【每日一练】什么是预编译?何时需要编译?
- 好用的笔记本散热器有哪些?九州风神N18散热器推荐_世界今亮点
- 在pycharm中运行代码时显示下面错误如何解决?
- 3999元起!长虹最新手机三款介绍评测来了
- 手机合约机和裸机有什么区别?合约机和裸机有什么好处?
- 为什么代购美国主机会便宜一些?老蒋告诉你真相:环球热推荐
- 模板文件css.htm制作教程 Discuz!模板文件的简单讲解
- 如何在12306网上订火车票官网退票?12306网上订火车票官网退票教程|当前最新
- 网上买手机哪个网站可靠?网上购买手机需要注意什么?_头条焦点
- 华为mate40Pro如何开启颜色反转?开启颜色反转方式:今日最新
- 0-12岁儿童身高体重标准表出炉 你家娃达标了吗?
- a820t联想怎么样?a820t联想基本参数及网友评测
- vuejs之Vue2.x中的父组件数据传递至子组件的方法
- 天天最新:在Ubuntu18.04、Deep终端中实现输入密码回显星号
- 天天简讯:在访问网页中弹出“脚本错误”的提示框 如何解决?
- 《绝地求生》主播打造3A级开放世界生存游戏新作 世界观热点
- 今年夏季《忍者小子》将改编成四人合作动作游戏
- 环球新动态:性价比绝了!中兴小方糖双频千兆路由器99元
- 不怕偷 哈罗电动车2373元
- 长江存储颗粒!梵想S500PRO 2TB M.2固态硬盘低至579元|环球观察
- 又曝大Bug!Windows 11会导致SSD速度降低
- 清仓大促销!AMD R5-5500板U套装低至789元
- 每日资讯:Roguelike策略卡牌游戏《河口蟾蜍》面向PC公布
- Epic喜+1:策略游戏《战锤40K:角斗士之战争圣器》 下周送《终极象棋》
- 《红霞岛》公布剧情预告 5月2日正式发售 快讯
- 特斯拉Model 3改装120寸大轮毂:暴力测试来了
- 天禄科技(301045):关于召开2023年第三次临时股东大会,审议《关于公司符合向特定对象发行股票条件的议案》等议案
- 观速讯丨现实版GTA?美国劫匪偷直升机因操作失误当场坠毁
- 《最终幻想起源:天堂的陌生人》4月登陆Steam-全球观点
- 确有其事还是开玩笑?刘德华将导演成龙吴京电影 世界热头条
- 张译新剧《他是谁》豆瓣大量好评!张译演技绝了-简讯
- 今日播报!外星人 m16 游戏本 RTX4050/4060/4070 开卖:15999 元起
- 今日精选:iPhone 14黄色版跌到5200 卖的格外好
- 即时焦点:马自达CX-50开售:58分钟卖出2000台
- 【天天播资讯】《最后生还者》艾莉妈妈演员晒幕后照:化妆超逼真
- 快看:微软与多家游戏平台签署COD协议 网友:就剩索尼了
- 世界最新:一段“诡异录像”里 藏着一位波兰小伙的游戏梦
- 诚信是老字号立身之本:环球视讯
- 闪购价,哈曼卡顿水晶 3 代音响仅售 999 元|焦点精选
- 汉印照片打印机CP2100:随心所印,留存美好
- 找工呀受邀参加汽车行业人资峰会,展示硬核招聘实力_环球微动态
- 环球今日报丨立省195元!16GB内存条崩盘价174元
- “绵阳造”上海行 长虹激光携光影耀申城
- 卡普空《恐龙浩劫》公测开启 残暴恐龙大军来袭
- 当前视讯!游民专访周董...的卫冕电竞战队Jteam
- 环球微速讯:《生化危机4:重制版》艾达王篇和佣兵模式或以DLC形式推出
- 文心一言秒变毕加索 看看百度AI画的青春校园女孩
- 环球聚焦:透明键盘超炫酷!戴尔背光机械键盘直降400元入手
- 调教Siri!苹果入局人工智能_环球微头条
- 王者荣耀体验服爆料:新增姐弟关系,基友关系改名