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

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

  1import static org.junit.Assert.*;2import org.junit.Test;345public class TestClone {67    @Test8    public void testClone(){9        // 西天取经的路上,金角大王和银角大王把唐僧抓走了10         猴王 齐天大圣=new 猴王("齐天大圣孙悟空");11        //大圣手拿金 箍棒,正要收拾金、银角大王。12        齐天大圣.取得武器(new 金箍棒());1314        /**//*15         * 这时候,金角大王和银角大王听闻大圣 来者不善,立马让小妖去请出他们的宝葫芦16         * 当然这一切瞒不过神通广大的 大圣爷。大圣猴毛一吹,变出一个老道士。17         */18        猴王 空悟孙道士=(猴王)齐天大圣.变出一个化身();19        空悟孙道士.改名("空悟孙道 士");2021        /**//*22         * 老道士忽悠小妖说他的葫 芦更厉害,能把天都给收了,智力值只有20的小妖看了羡慕不已,要求交换葫芦。23          * 老道士自然很乐意,换了葫芦,直奔妖怪洞穴,收服了金、银角大王。24          */25        空悟孙道士.取得武器(new 宝葫芦());2627        //问题1:道士拿的是什么武器?道士是由大圣克隆而来,拿的却不是金箍棒,而是宝葫芦?28         assertFalse(齐天大圣.的武器() instanceof 金箍棒);29        assertTrue(空悟孙道士.的武器() instanceof 宝葫芦);3031        //问题2:大 圣和道士拿同一个武器?32        assertSame(空悟孙道士.的武器(),齐天大圣.的武器 ());3334        //问题3:既然武器是一样的,为什么名字又不一样呢?35         assertEquals(齐天大圣.名字(),"齐天大圣孙悟空");36        assertEquals(空悟孙道士.名字(),"空悟孙道士");3738        /**//*39          * 答案:猴王类继承了Object.clone(),其克隆原理是:如果类每个域包含一个原语类 型(primitive)的值,40         * 或者包含一个指向非可变(final)对象的引用, 那么返回的值或对象是一个相同的拷贝;否则,如果是可变类,则会返回相同的引用。41          * 因为金箍棒类不是非可变类,而String是,所以你应该明白,为什么大圣爷和他的克隆体有 不同的名字,却有相同的武器吧。42         * 43         * Object.clone()被称为浅拷贝,或浅克隆。相对应的是深克隆(deep clone),他是指类在克隆时也拷贝 可变对象。44         * 看到这里你应该知道其实这个猴王类实现得不合理,他应该拥 有一个深克隆的方法。45         */46    }4748    class 猴王 implements Cloneable{49        private String name;50        private 武器[] weapon=new 武器[1]; 5152        public 猴王(String name) {53            this.name=name;54        }5556         /** *//**57         * 取得一个猴王的浅克隆化身58          * @return59         */60        public Object 变出一个化身 (){61            Object cloneObj=null;62            try {63                cloneObj=clone();64            } catch(CloneNotSupportedException ex){65                ex.printStackTrace();66            }67            return cloneObj;68        }6970        @Override71         protected Object clone() throws CloneNotSupportedException{72             return super.clone();73        }7475        public String 名字() {76            return name;77        }7879         public void 改名(String name){80            this.name=name;81        }8283        public 武器 的武器() {84            return weapon[0];85        }8687         public void 取得武器(武器 weapon) {88            this.weapon [0] = weapon;89        }90    }9192    class 武器{93        public 武器(){9495        }96    }9798    class 金箍棒 extends 武器{99        public 金箍棒(){100         }101    }102103    class 宝葫芦 extends 武器{104         public 宝葫芦(){105        }106    }107108109} 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;56import org.junit.Test;789public class TestDeepClone {1011    @Test12    public void testDeepClone(){13        // 西天取经的路上,金角大王和银角大王把唐 僧抓走了14        猴王 齐天大圣=new 猴王("齐天大圣孙悟空");15         //大圣手拿金箍棒,正要收拾金、银角大王。16        齐天大圣.取得武器(new 金箍 棒());1718        /**//*19         * 这时候,金角大王和银角 大王听闻大圣来者不善,立马让小妖去请出他们的宝葫芦20         * 当然这一切瞒不 过神通广大的大圣爷。大圣猴毛一吹,变出一个老道士。21         */22         猴王 空悟孙道士=(猴王)齐天大圣.变出一个化身();23        空悟孙道士.改 名("空悟孙道士");2425        /**//*26         * 老道士忽悠 小妖说他的葫芦更厉害,能把天都给收了,智力值只有20的小妖看了羡慕不已,要求交换葫芦。27          * 老道士自然很乐意,换了葫芦,直奔妖怪洞穴,收服了金、银角大王。28          */29        齐天大圣.取得武器(new 宝葫芦());303132        assertTrue(空悟孙道士.的武器() instanceof 金箍棒);33        assertFalse(空悟孙道士.的武器() instanceof 宝葫芦);34        assertNotSame(空悟 孙道士.的武器(),齐天大圣.的武器());35        assertEquals(齐天大圣.名字(),"齐天 大圣孙悟空");36        assertEquals(空悟孙道士.名字(),"空悟孙道士");37     }3839    class 猴王 implements Cloneable{40        private String name;41        private 武器 weapon; 4243        public 猴王(String name){44            this.name=name;45         }4647        /** *//**48         * 取得一个猴王的浅克隆 化身49         * @return50         */51        public Object 变出一个化身(){52            Object cloneObj=null;53             try{54                cloneObj=clone();55             }catch(CloneNotSupportedException ex){56                 ex.printStackTrace();57            }58            return cloneObj;59        }6061        /** *//**62          * 取得一个猴王的深克隆化身63         * @return64          */65        public Object 变出一个新化身(){66             Object cloneObj=null;67            try{68                 cloneObj=clone();69            }catch(CloneNotSupportedException ex){70                ex.printStackTrace();71             }72            return cloneObj;73        }7475         @Override76        protected Object clone() throws CloneNotSupportedException{77            return super.clone();78         }7980        public String 名字() {81             return name;82        }8384        public void 改名 (String name){85            this.name=name;86        }8788        public 武器 的武器() {89            return weapon;90        }9192        public void 取得武器(武器 weapon) {93            this.weapon = weapon;94        }95    }9697    abstract class 武器 implements Cloneable{98         public 武器(){99100        }101102        @Override103        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    }113114    class 金箍棒 extends 武器{115        public 金箍棒(){116        } 117118        @Override119        public Object clone(){120             return super.clone();121        }122    } 123124    class 宝葫芦 extends 武器{125        public 宝葫芦(){126         }127128        @Override129        public Object clone(){130            return super.clone();131        }132     }133}134

程序员的一生其实可短暂了,这电脑一开一关,一天过去了,嚎;电脑一开不关,那就成服务器了, 嚎……

积极的人在每一次忧患中都看到一个机会,

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

相关文章:

你感兴趣的文章:

标签云: