JAVA 对象拷贝

JAVA 对象拷贝

为什么需要有对象拷贝?

对象拷贝相对的自然是引用拷贝。java初学者经常会问,我这个方法要改变一个对象的属性,可以把参数传进去了,为什么没有改变了?

——基本数据类型传值,而对象传引用或引用的拷贝。

而有时候我们要获取到一个当前状态的对象复制品,他们是两个独立对象。不再是引用或者引用拷贝(实质都是指向对象本身)。就是说a是b的拷贝,b发生变化的时候,不要影响a。


对象拷贝有浅拷贝和深度拷贝两种。

1)浅拷贝

浅拷贝是指对象中基本数据类型得到拷贝,而引用数据类型并未拷贝。
提到拷贝自然和clone联系起来了,所有具有clone功能的类都有一个特性,那就是它直接或间接地实现了Cloneable接口。
否则,我们在尝试调用clone()方法时,将会触发CloneNotSupportedException异常。
eg:

 1 None.gif public   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.gif class  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.gif class  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    }

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值