程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> JAVA編程 >> 關於JAVA >> 大話深入淺出Effective Java核心實戰編程思想之猴王的把戲

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

編輯:關於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

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

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved