Heis的Blog

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

          大話深入淺出Effective Java核心實(shí)戰(zhàn)編程思想之——猴王的把戲

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

            1import static org.junit.Assert.*;
            2import org.junit.Test;
            3
            4
            5public class TestClone {
            6    
            7    @Test
            8    public void testClone(){    
            9        // 西天取經(jīng)的路上,金角大王和銀角大王把唐僧抓走了         
           10        猴王 齊天大圣=new 猴王("齊天大圣孫悟空");
           11        //大圣手拿金箍棒,正要收拾金、銀角大王。
           12        齊天大圣.取得武器(new 金箍棒());
           13        
           14        /*
           15         * 這時(shí)候,金角大王和銀角大王聽聞大圣來者不善,立馬讓小妖去請出他們的寶葫蘆
           16         * 當(dāng)然這一切瞞不過神通廣大的大圣爺。大圣猴毛一吹,變出一個(gè)老道士。
           17         */
                  
           18        猴王 空悟?qū)O道士=(猴王)齊天大圣.變出一個(gè)化身();
           19        空悟?qū)O道士.改名("空悟?qū)O道士");
           20        
           21        /*
           22         * 老道士忽悠小妖說他的葫蘆更厲害,能把天都給收了,智力值只有20的小妖看了羨慕不已,要求交換葫蘆。
           23         * 老道士自然很樂意,換了葫蘆,直奔妖怪洞穴,收服了金、銀角大王。
           24         */

           25        空悟?qū)O道士.取得武器(new 寶葫蘆());
           26        
           27        //問題1:道士拿的是什么武器?道士是由大圣克隆而來,拿的卻不是金箍棒,而是寶葫蘆?
           28        assertFalse(齊天大圣.的武器() instanceof 金箍棒);
           29        assertTrue(空悟?qū)O道士.的武器() instanceof 寶葫蘆);
           30        
           31        //問題2:大圣和道士拿同一個(gè)武器?
           32        assertSame(空悟?qū)O道士.的武器(),齊天大圣.的武器());
           33        
           34        //問題3:既然武器是一樣的,為什么名字又不一樣呢?
           35        assertEquals(齊天大圣.名字(),"齊天大圣孫悟空");
           36        assertEquals(空悟?qū)O道士.名字(),"空悟?qū)O道士");
           37        
           38        /*
           39         * 答案:猴王類繼承了Object.clone(),其克隆原理是:如果類每個(gè)域包含一個(gè)原語類型(primitive)的值,
           40         * 或者包含一個(gè)指向非可變(final)對象的引用,那么返回的值或?qū)ο笫且粋€(gè)相同的拷貝;否則,如果是可變類,則會返回相同的引用。
           41         * 因?yàn)榻鸸堪纛惒皇欠强勺冾悾鳶tring是,所以你應(yīng)該明白,為什么大圣爺和他的克隆體有不同的名字,卻有相同的武器吧。
           42         * 
           43         * Object.clone()被稱為淺拷貝,或淺克隆。相對應(yīng)的是深克?。╠eep clone),他是指類在克隆時(shí)也拷貝可變對象。
           44         * 看到這里你應(yīng)該知道其實(shí)這個(gè)猴王類實(shí)現(xiàn)得不合理,他應(yīng)該擁有一個(gè)深克隆的方法。
           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         * 取得一個(gè)猴王的淺克隆化身
           58         * @return
           59         */

           60        public Object 變出一個(gè)化身(){
           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

                  看到這里你應(yīng)該對深克隆和淺克隆有了初步的了解了吧?現(xiàn)在我們再看怎樣深克隆一個(gè)猴王,哦,不對,應(yīng)該是真正猴王的七十二變。(為什么我叫他猴王,因?yàn)閷O悟空有歧義)。
            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        // 西天取經(jīng)的路上,金角大王和銀角大王把唐僧抓走了         
           14        猴王 齊天大圣=new 猴王("齊天大圣孫悟空");
           15        //大圣手拿金箍棒,正要收拾金、銀角大王。
           16        齊天大圣.取得武器(new 金箍棒());
           17        
           18        /*
           19         * 這時(shí)候,金角大王和銀角大王聽聞大圣來者不善,立馬讓小妖去請出他們的寶葫蘆
           20         * 當(dāng)然這一切瞞不過神通廣大的大圣爺。大圣猴毛一吹,變出一個(gè)老道士。
           21         */
                  
           22        猴王 空悟?qū)O道士=(猴王)齊天大圣.變出一個(gè)化身();
           23        空悟?qū)O道士.改名("空悟?qū)O道士");
           24        
           25        /*
           26         * 老道士忽悠小妖說他的葫蘆更厲害,能把天都給收了,智力值只有20的小妖看了羨慕不已,要求交換葫蘆。
           27         * 老道士自然很樂意,換了葫蘆,直奔妖怪洞穴,收服了金、銀角大王。
           28         */

           29        齊天大圣.取得武器(new 寶葫蘆());
           30        
           31        
           32        assertTrue(空悟?qū)O道士.的武器() instanceof 金箍棒);
           33        assertFalse(空悟?qū)O道士.的武器() instanceof 寶葫蘆);
           34        assertNotSame(空悟?qū)O道士.的武器(),齊天大圣.的武器());
           35        assertEquals(齊天大圣.名字(),"齊天大圣孫悟空");
           36        assertEquals(空悟?qū)O道士.名字(),"空悟?qū)O道士");
           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         * 取得一個(gè)猴王的淺克隆化身
           49         * @return
           50         */

           51        public Object 變出一個(gè)化身(){
           52            Object cloneObj=null;
           53            try{
           54                cloneObj=clone();
           55            }
          catch(CloneNotSupportedException ex){
           56                ex.printStackTrace();
           57            }

           58            return cloneObj;
           59        }

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

           65        public Object 變出一個(gè)新化身(){
           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


          程序員的一生其實(shí)可短暫了,這電腦一開一關(guān),一天過去了,嚎;電腦一開不關(guān),那就成服務(wù)器了,嚎……

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

          評論

          # re: 大話深入淺出Effective Java核心實(shí)戰(zhàn)編程思想之——猴王的把戲  回復(fù)  更多評論   

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

          # re: 大話深入淺出Effective Java核心實(shí)戰(zhàn)編程思想之——猴王的把戲  回復(fù)  更多評論   

          寫的真好。學(xué)習(xí)了!
          2009-07-04 21:02 | 小人物

          # re: 大話深入淺出Effective Java核心實(shí)戰(zhàn)編程思想之——猴王的把戲  回復(fù)  更多評論   

          不錯(cuò)!
          2009-07-05 12:16 | 凡客誠品

          # re: 大話深入淺出Effective Java核心實(shí)戰(zhàn)編程思想之——猴王的把戲  回復(fù)  更多評論   

          不錯(cuò)
          2009-07-05 12:16 | 凡客誠品
          主站蜘蛛池模板: 历史| 江永县| 平遥县| 合山市| 东兰县| 孝义市| 广宁县| 翁牛特旗| 贵州省| 迁安市| 大安市| 石棉县| 壤塘县| 鹿邑县| 左贡县| 府谷县| 惠州市| 苍梧县| 永平县| 资源县| 五河县| 星座| 景泰县| 广昌县| 额尔古纳市| 开阳县| 山西省| 合川市| 井陉县| 崇义县| 广宗县| 龙井市| 汝城县| 普洱| 衡水市| 柳河县| 郸城县| 慈利县| 东安县| 德阳市| 新龙县|