Heis的Blog

          保持簡單,保持愚蠢
          隨筆 - 29, 文章 - 1, 評論 - 122, 引用 - 0
          數據加載中……

          大話深入淺出Effective Java核心實戰編程思想之——猴王的把戲

                  不知道大家還記不記得在《西游記》里的蓮花洞奪寶的故事,就是猴王巧奪寶物,收復金銀角大王那一章。到底這個故事給了我們什么啟示呢?這故事又和Effective Java有什么聯系?還是延續上篇文章的風格吧,看代碼,讀故事。

            1import static org.junit.Assert.*;
            2import org.junit.Test;
            3
            4
            5public 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

                  看到這里你應該對深克隆和淺克隆有了初步的了解了吧?現在我們再看怎樣深克隆一個猴王,哦,不對,應該是真正猴王的七十二變。(為什么我叫他猴王,因為孫悟空有歧義)。
            1import static org.junit.Assert.assertEquals;
            2import static org.junit.Assert.assertFalse;
            3import static org.junit.Assert.assertNotSame;
            4import static org.junit.Assert.assertTrue;
            5
            6import org.junit.Test;
            7
            8
            9public 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        public Object 變出一個化身(){
           52            Object cloneObj=null;
           53            try{
           54                cloneObj=clone();
           55            }
          catch(CloneNotSupportedException ex){
           56                ex.printStackTrace();
           57            }

           58            return cloneObj;
           59        }

           60        
           61        /**
           62         * 取得一個猴王的深克隆化身
           63         * @return
           64         */

           65        public Object 變出一個新化身(){
           66            Object cloneObj=null;
           67            try{
           68                cloneObj=clone();
           69            }
          catch(CloneNotSupportedException ex){
           70                ex.printStackTrace();
           71            }

           72            return cloneObj;
           73        }

           74        
           75        @Override
           76        protected Object clone() throws CloneNotSupportedException{
           77            return super.clone();
           78        }

           79        
           80        public String 名字() {
           81            return name;
           82        }

           83        
           84        public void 改名(String name){
           85            this.name=name;
           86        }

           87
           88        public 武器 的武器() {
           89            return weapon;
           90        }

           91
           92        public void 取得武器(武器 weapon) {
           93            this.weapon = weapon;
           94        }

           95    }

           96    
           97    abstract class 武器 implements Cloneable{
           98        public 武器(){
           99            
          100        }

          101        
          102        @Override
          103        public Object clone(){
          104            Object result=null;
          105            try{
          106                result= super.clone();
          107            }
          catch(CloneNotSupportedException ex){
          108                ex.printStackTrace();
          109            }

          110            return result;
          111        }

          112    }

          113    
          114    class 金箍棒 extends 武器{
          115        public 金箍棒(){
          116        }

          117        
          118        @Override
          119        public Object clone(){
          120            return super.clone();
          121        }

          122    }

          123    
          124    class 寶葫蘆 extends 武器{
          125        public 寶葫蘆(){
          126        }

          127        
          128        @Override
          129        public Object clone(){
          130            return super.clone();
          131        }

          132    }

          133}

          134


          程序員的一生其實可短暫了,這電腦一開一關,一天過去了,嚎;電腦一開不關,那就成服務器了,嚎……

          posted on 2009-07-04 14:37 Heis 閱讀(1737) 評論(4)  編輯  收藏 所屬分類: Effective Java

          評論

          # re: 大話深入淺出Effective Java核心實戰編程思想之——猴王的把戲  回復  更多評論   

          直奔妖怪洞穴,收服了金、銀角大王
          2009-07-04 16:44 | 99網上書店

          # re: 大話深入淺出Effective Java核心實戰編程思想之——猴王的把戲  回復  更多評論   

          寫的真好。學習了!
          2009-07-04 21:02 | 小人物

          # re: 大話深入淺出Effective Java核心實戰編程思想之——猴王的把戲  回復  更多評論   

          不錯!
          2009-07-05 12:16 | 凡客誠品

          # re: 大話深入淺出Effective Java核心實戰編程思想之——猴王的把戲  回復  更多評論   

          不錯
          2009-07-05 12:16 | 凡客誠品
          主站蜘蛛池模板: 绍兴市| 宁津县| 巴林右旗| 连城县| 松桃| 汶川县| 法库县| 怀化市| 专栏| 科尔| 宣威市| 沙坪坝区| 广昌县| 金华市| 禄劝| 临邑县| 河西区| 远安县| 本溪市| 广宁县| 翁牛特旗| 灵武市| 扎赉特旗| 阿拉尔市| 龙南县| 商洛市| 岳西县| 宜城市| 定日县| 遵化市| 扶余县| 鄄城县| 林州市| 石阡县| 乌恰县| 莎车县| 石棉县| 武威市| 长阳| 公安县| 鄂伦春自治旗|