JAVA 物件拷貝

iteye_13385發表於2008-04-28

JAVA 物件拷貝

為什麼需要有物件拷貝?

物件拷貝相對的自然是引用拷貝。java初學者經常會問,我這個方法要改變一個物件的屬性,可以把引數傳進去了,為什麼沒有改變了?

——基本資料型別傳值,而物件傳引用或引用的拷貝。

而有時候我們要獲取到一個當前狀態的物件複製品,他們是兩個獨立物件。不再是引用或者引用拷貝(實質都是指向物件本身)。就是說a是b的拷貝,b發生變化的時候,不要影響a。


物件拷貝有淺拷貝和深度拷貝兩種。

1)淺拷貝

淺拷貝是指物件中基本資料型別得到拷貝,而引用資料型別並未拷貝。
提到拷貝自然和clone聯絡起來了,所有具有clone功能的類都有一個特性,那就是它直接或間接地實現了Cloneable介面。
否則,我們在嘗試呼叫clone()方法時,將會觸發CloneNotSupportedException異常。
eg:

 1 None.gifpublic   class  DOG  implements  Cloneable
 2 ExpandedBlockStart.gifContractedBlock.gif dot.gif {
 3 InBlock.gif     public  DOG(String name,  int  age)
 4 ExpandedSubBlockStart.gifContractedSubBlock.gif     dot.gif {
 5 InBlock.gif         this .name  =  name;
 6 InBlock.gif         this .age  =  age;
 7 ExpandedSubBlockEnd.gif    }

 8 InBlock.gif
 9 InBlock.gif     public  String getName()
10 ExpandedSubBlockStart.gifContractedSubBlock.gif     dot.gif {
11 InBlock.gif         return   this .name;
12 ExpandedSubBlockEnd.gif    }

13 InBlock.gif
14 InBlock.gif     public   int  getAge()
15 ExpandedSubBlockStart.gifContractedSubBlock.gif     dot.gif {
16 InBlock.gif         return   this .age;
17 ExpandedSubBlockEnd.gif    }

18 InBlock.gif
19 InBlock.gif     public  Object clone()
20 ExpandedSubBlockStart.gifContractedSubBlock.gif     dot.gif {
21 InBlock.gif         try
22 ExpandedSubBlockStart.gifContractedSubBlock.gif         dot.gif {
23 InBlock.gif             return   super .clone();
24 InBlock.gif
25 ExpandedSubBlockEnd.gif        }
  catch  (CloneNotSupportedException e)
26 ExpandedSubBlockStart.gifContractedSubBlock.gif         dot.gif {
27 InBlock.gif             return   null ;
28 ExpandedSubBlockEnd.gif        }

29 ExpandedSubBlockEnd.gif    }

30 InBlock.gif
31 InBlock.gif     public  String name;
32 InBlock.gif
33 InBlock.gif     private   int  age;
34 InBlock.gif
35 InBlock.gif     // test
36 InBlock.gif      public   static   void  main(String[] args)
37 ExpandedSubBlockStart.gifContractedSubBlock.gif     dot.gif {
38 InBlock.gif        DOG dog1  =   new  DOG( " xiaogou " 2 );
39 InBlock.gif        DOG dog2  =  (DOG) dog1.clone();
40 InBlock.gif        dog1.name  =   " dagou " ;
41 InBlock.gif        System.out.println(dog2.getName());
42 InBlock.gif        System.out.println(dog2.getAge());
43 InBlock.gif        System.out.println(dog1.getName());
44 InBlock.gif        System.out.println(dog1.getAge());
45 InBlock.gif
46 ExpandedSubBlockEnd.gif    }

47 InBlock.gif
48 ExpandedBlockEnd.gif}

49 None.gif



執行結果:

xiaogou
2
dagou
2

2)深度拷貝

相對淺拷貝。實現物件中基本資料型別和引用資料型別的拷貝。

請先看下面程式碼:

 

 1 None.gifclass  AAA
 2 ExpandedBlockStart.gifContractedBlock.gif dot.gif {
 3 InBlock.gif     public  AAA(String name)
 4 ExpandedSubBlockStart.gifContractedSubBlock.gif     dot.gif {
 5 InBlock.gif         this .name  =  name;
 6 ExpandedSubBlockEnd.gif    }

 7 InBlock.gif
 8 InBlock.gif     public  String name;
 9 ExpandedBlockEnd.gif}

10 None.gif
11 None.gif class  DOG  implements  Cloneable
12 ExpandedBlockStart.gifContractedBlock.gif dot.gif {
13 InBlock.gif     public  DOG(String name,  int  age, AAA birthday)
14 ExpandedSubBlockStart.gifContractedSubBlock.gif     dot.gif {
15 InBlock.gif         this .name  =  name;
16 InBlock.gif         this .age  =  age;
17 InBlock.gif         this .birthday  =  birthday;
18 ExpandedSubBlockEnd.gif    }

19 InBlock.gif
20 InBlock.gif     public  String getName()
21 ExpandedSubBlockStart.gifContractedSubBlock.gif     dot.gif {
22 InBlock.gif         return  name;
23 ExpandedSubBlockEnd.gif    }

24 InBlock.gif
25 InBlock.gif     public   int  getAge()
26 ExpandedSubBlockStart.gifContractedSubBlock.gif     dot.gif {
27 InBlock.gif         return  age;
28 ExpandedSubBlockEnd.gif    }

29 InBlock.gif
30 InBlock.gif     public  AAA getBirthday()
31 ExpandedSubBlockStart.gifContractedSubBlock.gif     dot.gif {
32 InBlock.gif         return  birthday;
33 ExpandedSubBlockEnd.gif    }

34 InBlock.gif
35 InBlock.gif     public  String getBirth(AAA a)
36 ExpandedSubBlockStart.gifContractedSubBlock.gif     dot.gif {
37 InBlock.gif         return  a.name;
38 ExpandedSubBlockEnd.gif    }

39 InBlock.gif
40 InBlock.gif     public  String name;
41 InBlock.gif
42 InBlock.gif     private   int  age;
43 InBlock.gif
44 InBlock.gif     public  AAA birthday;
45 InBlock.gif
46 InBlock.gif     public  Object clone()
47 ExpandedSubBlockStart.gifContractedSubBlock.gif     dot.gif {
48 InBlock.gif         try
49 ExpandedSubBlockStart.gifContractedSubBlock.gif         dot.gif {
50 InBlock.gif             super .clone();
51 InBlock.gif             return   super .clone();
52 ExpandedSubBlockEnd.gif        }
  catch  (Exception e)
53 ExpandedSubBlockStart.gifContractedSubBlock.gif         dot.gif {
54 InBlock.gif             return   null ;
55 ExpandedSubBlockEnd.gif        }

56 ExpandedSubBlockEnd.gif    }

57 ExpandedBlockEnd.gif}

58 None.gif
59 None.gif public   class  TestClone
60 ExpandedBlockStart.gifContractedBlock.gif dot.gif {
61 InBlock.gif     public   static   void  main(String[] args)
62 ExpandedSubBlockStart.gifContractedSubBlock.gif     dot.gif {
63 InBlock.gif        AAA Day  =   new  AAA( " test " );
64 InBlock.gif        DOG dog1  =   new  DOG( " xiaogou " 2 , Day);
65 InBlock.gif        DOG dog2  =  (DOG) dog1.clone();
66 InBlock.gif         //   dog2.birthday = (AAA) dog1.birthday.clone(); 
67 InBlock.gif         dog1.birthday.name  =   " 333 " ;
68 InBlock.gif        System.out.println(dog1.getBirth(dog1.birthday));
69 InBlock.gif        System.out.println(dog2.getBirth(dog2.birthday));
70 ExpandedSubBlockEnd.gif    }

71 ExpandedBlockEnd.gif}

72 None.gif


執行結果是:
333
333
而真正要實現拷貝還的加點程式碼,如下請對比上面和下面程式碼的異同之處:

 1 None.gifclass  AAA  implements  Cloneable
 2 ExpandedBlockStart.gifContractedBlock.gif dot.gif {
 3 InBlock.gif     public  AAA(String name)
 4 ExpandedSubBlockStart.gifContractedSubBlock.gif     dot.gif {
 5 InBlock.gif         this .name  =  name;
 6 ExpandedSubBlockEnd.gif    }

 7 InBlock.gif
 8 InBlock.gif     public  Object clone()
 9 ExpandedSubBlockStart.gifContractedSubBlock.gif     dot.gif {
10 InBlock.gif         try
11 ExpandedSubBlockStart.gifContractedSubBlock.gif         dot.gif {
12 InBlock.gif             super .clone();
13 InBlock.gif             return   super .clone();
14 ExpandedSubBlockEnd.gif        }
  catch  (Exception e)
15 ExpandedSubBlockStart.gifContractedSubBlock.gif         dot.gif {
16 InBlock.gif             return   null ;
17 ExpandedSubBlockEnd.gif        }

18 ExpandedSubBlockEnd.gif    }

19 InBlock.gif
20 InBlock.gif     public  String name;
21 ExpandedBlockEnd.gif}

22 None.gif
23 None.gif class  DOG  implements  Cloneable
24 ExpandedBlockStart.gifContractedBlock.gif dot.gif {
25 InBlock.gif     public  DOG(String name,  int  age, AAA birthday)
26 ExpandedSubBlockStart.gifContractedSubBlock.gif     dot.gif {
27 InBlock.gif         this .name  =  name;
28 InBlock.gif         this .age  =  age;
29 InBlock.gif         this .birthday  =  birthday;
30 ExpandedSubBlockEnd.gif    }

相關文章