亚洲免费在线-亚洲免费在线播放-亚洲免费在线观看-亚洲免费在线观看视频-亚洲免费在线看-亚洲免费在线视频

java clone方法使用詳解

系統 1764 0

Java語言的一個優點就是取消了指針的概念,但也導致了許多程序員在編程中常常忽略了對象與引用的區別,特別是先學c、c++后學java的程序員。并且由于Java不能通過簡單的賦值來解決對象復制的問題,在開發過程中,也常常要要應用clone()方法來復制對象。比如函數參數類型是自定義的類時,此時便是引用傳遞而不是值傳遞。以下是一個小例子:

1 public class A {??
2 ??? public String name;??
3 }
4 public class testClone {??????????
5 ???? public void changeA(A a){??
6 ????????? a.name="b" ;??
7 ???? }??
8 ????? public void changInt( int i){??
9 ????????? i=i*2+100 ;??
10 ???? }??
11 ????????
12 ????? /** ?
13 ????? * @param args?
14 ?????? */ ?
15 ????? public static void main(String[] args) {??
16 ????????? // TODO Auto-generated method stub??
17 ????????? testClone test= new testClone();??
18 ????????? A a= new A();??
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= new A();
2 ?? A a2= new A();
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 implements Cloneable 2 {
3 ???? public String name;
4
5 ???? public Object clone()
6 ??? {
7 ???????? A o = null ;
8 ???????? try
9 ??????? {
10 ???????????? o = (A) super .clone();
11 ???????? } catch (CloneNotSupportedException e)
12 ??????? {
13 e.printStackTrace(); 14 ??????? }
15 ???????? return o;
16 ??? }
17 }

復制代碼

首先要實現Cloneable接口,然后在重載clone方法,最后在clone()方法中調用了super.clone(),這也意味著無論clone類的繼承結構是什么樣的,super.clone()直接或間接調用了java.lang.Object類的clone()方法。

1 A a1 = new A();
2 A a2 = new A();
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 implements Cloneable 2 {
3 ???? public String name[];
4
5 ???? public A()
6 ??? {
7 ???????? name = new String[2 ];
8 ??? }
9
10 ???? public Object clone()
11 ??? {
12 ???????? A o = null ;
13 ???????? try
14 ??????? {
15 ???????????? o = (A) super .clone();
16 ???????? } catch (CloneNotSupportedException e)
17 ??????? {
18 e.printStackTrace(); 19 ??????? }
20 ???????? return o;
21 ??? }
22 }

復制代碼

測試代碼

1 A a1= new A();
2 A a2= new A();
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 public Object 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 ???????? return o;
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 implements Cloneable {??
2 ????? public String name[];??
3 ????? public Vector<B> claB;??
4 ????????
5 ????? public A(){??
6 ????????? name= new String[2 ];??
7 ????????? claB= new Vector<B> ();??
8 ???? }??
9 ???
10 ????? public Object 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<B>(); // 將clone進行到底??
19 ????????? for ( int i=0;i<claB.size();i++ ){??
20 ????????????? B temp=(B)claB.get(i).clone(); // 當然Class B也要實現相應clone方法
21 ???????????? o.claB.add(temp);??
22 ???????? }??
23 ????????? return o;??
24 ???? }??
25 ? }

java clone方法使用詳解


更多文章、技術交流、商務合作、聯系博主

微信掃碼或搜索:z360901061

微信掃一掃加我為好友

QQ號聯系: 360901061

您的支持是博主寫作最大的動力,如果您喜歡我的文章,感覺我的文章對您有幫助,請用微信掃描下面二維碼支持博主2元、5元、10元、20元等您想捐的金額吧,狠狠點擊下面給點支持吧,站長非常感激您!手機微信長按不能支付解決辦法:請將微信支付二維碼保存到相冊,切換到微信,然后點擊微信右上角掃一掃功能,選擇支付二維碼完成支付。

【本文對您有幫助就好】

您的支持是博主寫作最大的動力,如果您喜歡我的文章,感覺我的文章對您有幫助,請用微信掃描上面二維碼支持博主2元、5元、10元、自定義金額等您想捐的金額吧,站長會非常 感謝您的哦!!!

發表我的評論
最新評論 總共0條評論
主站蜘蛛池模板: 欧美一区二区三区影院 | 女人十八毛片一级毛片免费看 | 日本一视频一区视频二区 | 青青草这里只有精品 | 精品久久伊人 | 亚洲涩综合 | 波多野结衣一区二区 三区 波多野结衣一区二区三区 波多野结衣一区二区三区高清在线 | 99麻豆久久久国产精品免费 | 综合欧美亚洲 | 最近中文字幕无吗高清视频 | 99久久香蕉国产综合影院 | 日本不卡视频在线播放 | 老司机午夜在线视频免费观 | 欧洲成人免费高清视频 | 亚洲另类中文字幕 | 精品亚洲欧美高清不卡高清 | 国产1区2区三区不卡 | 91热精品 | 婷婷在线成人免费观看搜索 | 亚洲欧美日韩综合 | 99久久精品国产一区二区 | 亚洲精品成人456在线播放 | 天天摸天天操 | 福利网站在线观看 | 调教师鞭打总裁奴男男 | 日韩视频免费在线播放 | 久久专区| 婷婷综合 | 九天玄帝诀王凡小说免费阅读 | 91论坛在线 | 一区二区三区精品国产欧美 | 涩综合 | 奇米第四色7777 | 日韩欧美国产中文字幕 | 久久99精品久久久久久青青日本 | 久久精品中文字幕久久 | 性欧美极品xxxx欧美一区二区 | 在线观看亚洲视频 | 欧美一级毛片免费看高清 | 你懂得国产 | 在线500福利视频国产 |