`
Heis
  • 浏览: 112416 次
  • 性别: Icon_minigender_1
  • 来自: 深圳
社区版块
存档分类
最新评论

大话深入浅出Effective Java核心实战编程思想之——猴王的把戏

阅读更多

不知道大家还记不记得在《西游记》里的莲花洞夺宝的故事,就是猴王巧夺宝物,收复金银角大王那一章。到底这个故事给了我们什么启示呢?这故事又和Effective Java有什么联系?还是延续上篇文章的风格吧,看代码,读故事。

  1 import   static  org.junit.Assert. * ;
  2 import  org.junit.Test;
  3
  4
  5 public   class  TestClone  {
  6     
  7     @Test
  8      public   void  testClone() {    
  9          //  西天取经的路上,金角大王和银角大王把唐僧抓走了         
 10         猴王 齐天大圣 = new  猴王( " 齐天大圣孙悟空 " );
 11          // 大圣手拿金箍棒,正要收拾金、银角大王。
 12         齐天大圣.取得武器( new  金箍棒());
 13         
 14          /**/ /*
 15          * 这时候,金角大王和银角大王听闻大圣来者不善,立马让小妖去请出他们的宝葫芦
 16          * 当然这一切瞒不过神通广大的大圣爷。大圣猴毛一吹,变出一个老道士。
 17           */
        
 18         猴王 空悟孙道士 = (猴王)齐天大圣.变出一个化身();
 19         空悟孙道士.改名( " 空悟孙道士 " );
 20         
 21          /**/ /*
 22          * 老道士忽悠小妖说他的葫芦更厉害,能把天都给收了,智力值只有20的小妖看了羡慕不已,要求交换葫芦。
 23          * 老道士自然很乐意,换了葫芦,直奔妖怪洞穴,收服了金、银角大王。
 24           */

 25         空悟孙道士.取得武器( new  宝葫芦());
 26         
 27          // 问题1:道士拿的是什么武器?道士是由大圣克隆而来,拿的却不是金箍棒,而是宝葫芦?
 28         assertFalse(齐天大圣.的武器()  instanceof  金箍棒);
 29         assertTrue(空悟孙道士.的武器()  instanceof  宝葫芦);
 30         
 31          // 问题2:大圣和道士拿同一个武器?
 32         assertSame(空悟孙道士.的武器(),齐天大圣.的武器());
 33         
 34          // 问题3:既然武器是一样的,为什么名字又不一样呢?
 35         assertEquals(齐天大圣.名字(), " 齐天大圣孙悟空 " );
 36         assertEquals(空悟孙道士.名字(), " 空悟孙道士 " );
 37         
 38          /**/ /*
 39          * 答案:猴王类继承了Object.clone(),其克隆原理是:如果类每个域包含一个原语类型(primitive)的值,
 40          * 或者包含一个指向非可变(final)对象的引用,那么返回的值或对象是一个相同的拷贝;否则,如果是可变类,则会返回相同的引用。
 41          * 因为金箍棒类不是非可变类,而String是,所以你应该明白,为什么大圣爷和他的克隆体有不同的名字,却有相同的武器吧。
 42          * 
 43          * Object.clone()被称为浅拷贝,或浅克隆。相对应的是深克隆(deep clone),他是指类在克隆时也拷贝可变对象。
 44          * 看到这里你应该知道其实这个猴王类实现得不合理,他应该拥有一个深克隆的方法。
 45           */

 46     }

 47
 48      class  猴王  implements  Cloneable {
 49          private  String name;
 50          private  武器[] weapon = new  武器[ 1 ]; 
 51         
 52          public  猴王(String name) {
 53              this .name = name;
 54         }

 55             
 56          /** */ /**
 57          * 取得一个猴王的浅克隆化身
 58          *  @return
 59           */

 60          public  Object 变出一个化身() {
 61             Object cloneObj = null ;
 62              try {
 63                 cloneObj = clone();
 64             }
catch (CloneNotSupportedException ex) {
 65                 ex.printStackTrace();
 66             }

 67              return  cloneObj;
 68         }

 69         
 70         @Override
 71          protected  Object clone()  throws  CloneNotSupportedException {
 72              return   super .clone();
 73         }

 74         
 75          public  String 名字()  {
 76              return  name;
 77         }

 78         
 79          public   void  改名(String name) {
 80              this .name = name;
 81         }

 82
 83          public  武器 的武器()  {
 84              return  weapon[ 0 ];
 85         }

 86
 87          public   void  取得武器(武器 weapon)  {
 88              this .weapon[ 0 =  weapon;
 89         }

 90     }

 91     
 92      class  武器 {
 93          public  武器() {
 94             
 95         }

 96     }

 97     
 98      class  金箍棒  extends  武器 {
 99          public  金箍棒() {
100         }

101     }

102     
103      class  宝葫芦  extends  武器 {
104          public  宝葫芦() {
105         }

106     }

107     
108
109 }

110


        看到这里你应该对深克隆和浅克隆有了初步的了解了吧?现在我们再看怎样深克隆一个猴王,哦,不对,应该是真正猴王的七十二变。(为什么我叫他猴王,因为孙悟空有歧义)。

  1 import   static  org.junit.Assert.assertEquals;
  2 import   static  org.junit.Assert.assertFalse;
  3 import   static  org.junit.Assert.assertNotSame;
  4 import   static  org.junit.Assert.assertTrue;
  5
  6 import  org.junit.Test;
  7
  8
  9 public   class  TestDeepClone  {
 10         
 11     @Test
 12      public   void  testDeepClone() {    
 13          //  西天取经的路上,金角大王和银角大王把唐僧抓走了         
 14         猴王 齐天大圣 = new  猴王( " 齐天大圣孙悟空 " );
 15          // 大圣手拿金箍棒,正要收拾金、银角大王。
 16         齐天大圣.取得武器( new  金箍棒());
 17         
 18          /**/ /*
 19          * 这时候,金角大王和银角大王听闻大圣来者不善,立马让小妖去请出他们的宝葫芦
 20          * 当然这一切瞒不过神通广大的大圣爷。大圣猴毛一吹,变出一个老道士。
 21           */
        
 22         猴王 空悟孙道士 = (猴王)齐天大圣.变出一个化身();
 23         空悟孙道士.改名( " 空悟孙道士 " );
 24         
 25          /**/ /*
 26          * 老道士忽悠小妖说他的葫芦更厉害,能把天都给收了,智力值只有20的小妖看了羡慕不已,要求交换葫芦。
 27          * 老道士自然很乐意,换了葫芦,直奔妖怪洞穴,收服了金、银角大王。
 28           */

 29         齐天大圣.取得武器( new  宝葫芦());
 30         
 31         
 32         assertTrue(空悟孙道士.的武器()  instanceof  金箍棒);
 33         assertFalse(空悟孙道士.的武器()  instanceof  宝葫芦);
 34         assertNotSame(空悟孙道士.的武器(),齐天大圣.的武器());
 35         assertEquals(齐天大圣.名字(), " 齐天大圣孙悟空 " );
 36         assertEquals(空悟孙道士.名字(), " 空悟孙道士 " );
 37     }

 38     
 39      class  猴王  implements  Cloneable {
 40          private  String name;
 41          private  武器 weapon; 
 42         
 43          public  猴王(String name) {
 44              this .name = name;
 45         }

 46             
 47          /** */ /**
 48          * 取得一个猴王的浅克隆化身
 49          *  @return
 50           */

 51</sp
1
0
分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics