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

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條評論
主站蜘蛛池模板: 热热涩热热狠狠色香蕉综合 | 男人午夜剧场 | 福利视频二区 | 毛片色毛片18毛片美女 | 日韩欧美一区二区久久黑人 | 国产精品久久久久久久免费 | 成人在线观看一区 | 日韩大片在线 | 九九综合九九 | 国产短视频精品区第一页 | 无遮挡一级毛片呦女视频 | 亚洲视频在线观看免费视频 | 男女乱淫真视频免费一级毛片 | 中文字幕高清免费不卡视频 | 99久久综合狠狠综合久久一区 | 九九香蕉| 日日摸夜夜爽夜夜爽出水 | 国产日韩欧美在线观看免费视频 | 中文字幕久久久久久久系列 | 日韩人成免费网站大片 | 色综合网亚洲精品久久久 | 国产亚洲精品精品国产亚洲综合 | 麻豆国产在线观看一区二区 | 欧美精品一区二区三区久久 | 成人欧美一区二区三区黑人妖 | 热久久精品免费视频 | 一级毛片特级毛片免费的 | 午夜dj影院在线视频观看完整 | 日韩黄a级成人毛片 | 婷婷性 | 在线观看亚洲精品专区 | 久久久视频在线 | 久久精品国产大片免费观看 | 亚洲一级毛片视频 | 欧美成人a视频 | 四虎在线播放免费永久视频 | 国产日本欧美在线观看 | 99久久www免费 | 中文字幕 亚洲精品 第1页 | 一级片免费视频 | 一本大道久久a久久综合 |