原創(chuàng)|其它|編輯:郝浩|2009-07-09 11:27:54.000|閱讀 352 次
概述:不知道大家還記不記得在《西游記》里的蓮花洞奪寶的故事,就是猴王巧奪寶物,收復(fù)金銀角大王那一章。到底這個(gè)故事給了我們什么啟示呢?這故事又和Effective Java有什么聯(lián)系?還是延續(xù)上篇文章的風(fēng)格吧,看代碼,讀故事。
# 界面/圖表報(bào)表/文檔/IDE等千款熱門軟控件火熱銷售中 >>
不知道大家還記不記得在《西游記》里的蓮花洞奪寶的故事,就是猴王巧奪寶物,收復(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í)候,金角大王和銀角大王聽聞大圣來者不善,立馬讓小妖去請(qǐng)出他們的寶葫蘆
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)對(duì)象的引用,那么返回的值或?qū)ο笫且粋€(gè)相同的拷貝;否則,如果是可變類,則會(huì)返回相同的引用。
41 * 因?yàn)榻鸸堪纛惒皇欠强勺冾悾鳶tring是,所以你應(yīng)該明白,為什么大圣爺和他的克隆體有不同的名字,卻有相同的武器吧。
42 *
43 * Object.clone()被稱為淺拷貝,或淺克隆。相對(duì)應(yīng)的是深克隆(deep clone),他是指類在克隆時(shí)也拷貝可變對(duì)象。
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)該對(duì)深克隆和淺克隆有了初步的了解了吧?現(xiàn)在我們?cè)倏丛鯓由羁寺∫粋€(gè)猴王,哦,不對(duì),應(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í)候,金角大王和銀角大王聽聞大圣來者不善,立馬讓小妖去請(qǐng)出他們的寶葫蘆
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
本站文章除注明轉(zhuǎn)載外,均為本站原創(chuàng)或翻譯。歡迎任何形式的轉(zhuǎn)載,但請(qǐng)務(wù)必注明出處、不得修改原文相關(guān)鏈接,如果存在內(nèi)容上的異議請(qǐng)郵件反饋至chenjj@fc6vip.cn
文章轉(zhuǎn)載自:IT專家網(wǎng)論壇