亚洲欧美第一页_禁久久精品乱码_粉嫩av一区二区三区免费野_久草精品视频

? 歡迎來到蟲蟲下載站! | ?? 資源下載 ?? 資源專輯 ?? 關(guān)于我們
? 蟲蟲下載站

?? chapter12.htm

?? Thinking In Java第二版(中文)
?? HTM
?? 第 1 頁 / 共 4 頁
字號:
<html>

<head>
<meta http-equiv="Content-Type" content="text/html; charset=gb2312">
<title>Thinking in Java | Chinese Version by Trans Bot</title>

<meta name="Microsoft Theme" content="inmotion 111, default"></head>

<body background="../_themes/inmotion/inmtextb.gif" tppabs="http://member.netease.com/%7etransbot/Thinking%20in%20Java/_themes/inmotion/inmtextb.gif" bgcolor="#FFFFCC" text="#000000" link="#800000" vlink="#996633" alink="#FF3399">

<p>第12章 傳遞和返回對象<br>
<br>
到目前為止,讀者應(yīng)對對象的“傳遞”有了一個較為深刻的認識,記住實際傳遞的只是一個句柄。<br>
在許多程序設(shè)計語言中,我們可用語言的“普通”方式到處傳遞對象,而且大多數(shù)時候都不會遇到問題。但有些時候卻不得不采取一些非常做法,使得情況突然變得稍微復(fù)雜起來(在C++中則是變得非常復(fù)雜)。Java亦不例外,我們十分有必要準確認識在對象傳遞和賦值時所發(fā)生的一切。這正是本章的宗旨。<br>
若讀者是從某些特殊的程序設(shè)計環(huán)境中轉(zhuǎn)移過來的,那么一般都會問到:“Java有指針嗎?”有些人認為指針的操作很困難,而且十分危險,所以一廂情愿地認為它沒有好處。同時由于Java有如此好的口碑,所以應(yīng)該很輕易地免除自己以前編程中的麻煩,其中不可能夾帶有指針這樣的“危險品”。然而準確地說,Java是有指針的!事實上,Java中每個對象(除基本數(shù)據(jù)類型以外)的標識符都屬于指針的一種。但它們的使用受到了嚴格的限制和防范,不僅編譯器對它們有“戒心”,運行期系統(tǒng)也不例外。或者換從另一個角度說,Java有指針,但沒有傳統(tǒng)指針的麻煩。我曾一度將這種指針叫做“句柄”,但你可以把它想像成“安全指針”。和預(yù)備學(xué)校為學(xué)生提供的安全剪刀類似——除非特別有意,否則不會傷著自己,只不過有時要慢慢來,要習(xí)慣一些沉悶的工作。<br>
<br>
12.1 傳遞句柄<br>
將句柄傳遞進入一個方法時,指向的仍然是相同的對象。一個簡單的實驗可以證明這一點(若執(zhí)行這個程序時有麻煩,請參考第3章3.1.2小節(jié)“賦值”):<br>
<br>
542頁程序<br>
<br>
toString方法會在打印語句里自動調(diào)用,而PassHandles直接從Object繼承,沒有toString的重新定義。因此,這里會采用toString的Object版本,打印出對象的類,接著是那個對象所在的位置(不是句柄,而是對象的實際存儲位置)。輸出結(jié)果如下:<br>
p inside main(): PassHandles@1653748<br>
h inside f() : PassHandles@1653748<br>
可以看到,無論p還是h引用的都是同一個對象。這比復(fù)制一個新的PassHandles對象有效多了,使我們能將一個參數(shù)發(fā)給一個方法。但這樣做也帶來了另一個重要的問題。<br>
<br>
12.1.1 別名問題<br>
“別名”意味著多個句柄都試圖指向同一個對象,就象前面的例子展示的那樣。若有人向那個對象里寫入一點什么東西,就會產(chǎn)生別名問題。若其他句柄的所有者不希望那個對象改變,恐怕就要失望了。這可用下面這個簡單的例子說明:<br>
<br>
543頁程序<br>
<br>
對下面這行:<br>
Alias1 y = x; // Assign the handle<br>
它會新建一個Alias1句柄,但不是把它分配給由new創(chuàng)建的一個新鮮對象,而是分配給一個現(xiàn)有的句柄。所以句柄x的內(nèi)容——即對象x指向的地址——被分配給y,所以無論x還是y都與相同的對象連接起來。這樣一來,一旦x的i在下述語句中增值:<br>
x.i++;<br>
y的i值也必然受到影響。從最終的輸出就可以看出:<br>
<br>
544頁上程序<br>
<br>
此時最直接的一個解決辦法就是干脆不這樣做:不要有意將多個句柄指向同一個作用域內(nèi)的同一個對象。這樣做可使代碼更易理解和調(diào)試。然而,一旦準備將句柄作為一個自變量或參數(shù)傳遞——這是Java設(shè)想的正常方法——別名問題就會自動出現(xiàn),因為創(chuàng)建的本地句柄可能修改“外部對象”(在方法作用域之外創(chuàng)建的對象)。下面是一個例子:<br>
<br>
544頁程序<br>
<br>
輸出如下:<br>
x: 7<br>
Calling f(x)<br>
x: 8<br>
<br>
方法改變了自己的參數(shù)——外部對象。一旦遇到這種情況,必須判斷它是否合理,用戶是否愿意這樣,以及是不是會造成問題。<br>
通常,我們調(diào)用一個方法是為了產(chǎn)生返回值,或者用它改變?yōu)槠湔{(diào)用方法的那個對象的狀態(tài)(方法其實就是我們向那個對象“發(fā)一條消息”的方式)。很少需要調(diào)用一個方法來處理它的參數(shù);這叫作利用方法的“副作用”(Side 
Effect)。所以倘若創(chuàng)建一個會修改自己參數(shù)的方法,必須向用戶明確地指出這一情況,并警告使用那個方法可能會有的后果以及它的潛在威脅。由于存在這些混淆和缺陷,所以應(yīng)該盡量避免改變參數(shù)。<br>
若需在一個方法調(diào)用期間修改一個參數(shù),且不打算修改外部參數(shù),就應(yīng)在自己的方法內(nèi)部制作一個副本,從而保護那個參數(shù)。本章的大多數(shù)內(nèi)容都是圍繞這個問題展開的。<br>
<br>
12.2 制作本地副本<br>
稍微總結(jié)一下:Java中的所有自變量或參數(shù)傳遞都是通過傳遞句柄進行的。也就是說,當我們傳遞“一個對象”時,實際傳遞的只是指向位于方法外部的那個對象的“一個句柄”。所以一旦要對那個句柄進行任何修改,便相當于修改外部對象。此外:<br>
■參數(shù)傳遞過程中會自動產(chǎn)生別名問題<br>
■不存在本地對象,只有本地句柄<br>
■句柄有自己的作用域,而對象沒有<br>
■對象的“存在時間”在Java里不是個問題<br>
■沒有語言上的支持(如常量)可防止對象被修改(以避免別名的副作用)<br>
若只是從對象中讀取信息,而不修改它,傳遞句柄便是自變量傳遞中最有效的一種形式。這種做非常恰當;默認的方法一般也是最有效的方法。然而,有時仍需將對象當作“本地的”對待,使我們作出的改變只影響一個本地副本,不會對外面的對象造成影響。許多程序設(shè)計語言都支持在方法內(nèi)自動生成外部對象的一個本地副本(注釋①)。盡管Java不具備這種能力,但允許我們達到同樣的效果。<br>
<br>
①:在C語言中,通常控制的是少量數(shù)據(jù)位,默認操作是按值傳遞。C++也必須遵照這一形式,但按值傳遞對象并非肯定是一種有效的方式。此外,在C++中用于支持按值傳遞的代碼也較難編寫,是件讓人頭痛的事情。<br>
<br>
12.2.1 按值傳遞<br>
首先要解決術(shù)語的問題,最適合“按值傳遞”的看起來是自變量。“按值傳遞”以及它的含義取決于如何理解程序的運行方式。最常見的意思是獲得要傳遞的任何東西的一個本地副本,但這里真正的問題是如何看待自己準備傳遞的東西。對于“按值傳遞”的含義,目前存在兩種存在明顯區(qū)別的見解:<br>
(1) Java按值傳遞任何東西。若將基本數(shù)據(jù)類型傳遞進入一個方法,會明確得到基本數(shù)據(jù)類型的一個副本。但若將一個句柄傳遞進入方法,得到的是句柄的副本。所以人們認為“一切”都按值傳遞。當然,這種說法也有一個前提:句柄肯定也會被傳遞。但Java的設(shè)計方案似乎有些超前,允許我們忽略(大多數(shù)時候)自己處理的是一個句柄。也就是說,它允許我們將句柄假想成“對象”,因為在發(fā)出方法調(diào)用時,系統(tǒng)會自動照管兩者間的差異。<br>
(2) Java主要按值傳遞(無自變量),但對象卻是按引用傳遞的。得到這個結(jié)論的前提是句柄只是對象的一個“別名”,所以不考慮傳遞句柄的問題,而是直接指出“我準備傳遞對象”。由于將其傳遞進入一個方法時沒有獲得對象的一個本地副本,所以對象顯然不是按值傳遞的。Sun公司似乎在某種程度上支持這一見解,因為它“保留但未實現(xiàn)”的關(guān)鍵字之一便是byvalue(按值)。但沒人知道那個關(guān)鍵字什么時候可以發(fā)揮作用。<br>
盡管存在兩種不同的見解,但其間的分歧歸根到底是由于對“句柄”的不同解釋造成的。我打算在本書剩下的部分里回避這個問題。大家不久就會知道,這個問題爭論下去其實是沒有意義的——最重要的是理解一個句柄的傳遞會使調(diào)用者的對象發(fā)生意外的改變。<br>
<br>
12.2.2 克隆對象<br>
若需修改一個對象,同時不想改變調(diào)用者的對象,就要制作該對象的一個本地副本。這也是本地副本最常見的一種用途。若決定制作一個本地副本,只需簡單地使用clone()方法即可。Clone是“克隆”的意思,即制作完全一模一樣的副本。這個方法在基礎(chǔ)類Object中定義成“protected”(受保護)模式。但在希望克隆的任何衍生類中,必須將其覆蓋為“public”模式。例如,標準庫類Vector覆蓋了clone(),所以能為Vector調(diào)用clone(),如下所示:<br>
<br>
547頁程序<br>
<br>
clone()方法產(chǎn)生了一個Object,后者必須立即重新造型為正確類型。這個例子指出Vector的clone()方法不能自動嘗試克隆Vector內(nèi)包含的每個對象——由于別名問題,老的Vector和克隆的Vector都包含了相同的對象。我們通常把這種情況叫作“簡單復(fù)制”或者“淺層復(fù)制”,因為它只復(fù)制了一個對象的“表面”部分。實際對象除包含這個“表面”以外,還包括句柄指向的所有對象,以及那些對象又指向的其他所有對象,由此類推。這便是“對象網(wǎng)”或“對象關(guān)系網(wǎng)”的由來。若能復(fù)制下所有這張網(wǎng),便叫作“全面復(fù)制”或者“深層復(fù)制”。<br>
在輸出中可看到淺層復(fù)制的結(jié)果,注意對v2采取的行動也會影響到v:<br>
<br>
548頁上程序<br>
<br>
一般來說,由于不敢保證Vector里包含的對象是“可以克隆”(注釋②)的,所以最好不要試圖克隆那些對象。<br>
<br>
②:“可以克隆”用英語講是cloneable,請留意Java庫中專門保留了這樣的一個關(guān)鍵字。<br>
<br>
12.2.3 使類具有克隆能力<br>
盡管克隆方法是在所有類最基本的Object中定義的,但克隆仍然不會在每個類里自動進行。這似乎有些不可思議,因為基礎(chǔ)類方法在衍生類里是肯定能用的。但Java確實有點兒反其道而行之;如果想在一個類里使用克隆方法,唯一的辦法就是專門添加一些代碼,以便保證克隆的正常進行。<br>
<br>
1. 使用protected時的技巧<br>
為避免我們創(chuàng)建的每個類都默認具有克隆能力,clone()方法在基礎(chǔ)類Object里得到了“保留”(設(shè)為protected)。這樣造成的后果就是:對那些簡單地使用一下這個類的客戶程序員來說,他們不會默認地擁有這個方法;其次,我們不能利用指向基礎(chǔ)類的一個句柄來調(diào)用clone()(盡管那樣做在某些情況下特別有用,比如用多形性的方式克隆一系列對象)。在編譯期的時候,這實際是通知我們對象不可克隆的一種方式——而且最奇怪的是,Java庫中的大多數(shù)類都不能克隆。因此,假如我們執(zhí)行下述代碼:<br>
Integer x = new Integer(l);<br>
x = x.clone();<br>
那么在編譯期,就有一條討厭的錯誤消息彈出,告訴我們不可訪問clone()——因為Integer并沒有覆蓋它,而且它對protected版本來說是默認的)。<br>
但是,假若我們是在一個從Object衍生出來的類中(所有類都是從Object衍生的),就有權(quán)調(diào)用Object.clone(),因為它是“protected”,而且我們在一個繼承器中。基礎(chǔ)類clone()提供了一個有用的功能——它進行的是對衍生類對象的真正“按位”復(fù)制,所以相當于標準的克隆行動。然而,我們隨后需要將自己的克隆操作設(shè)為public,否則無法訪問。總之,克隆時要注意的兩個關(guān)鍵問題是:幾乎肯定要調(diào)用super.clone(),以及注意將克隆設(shè)為public。<br>
有時還想在更深層的衍生類中覆蓋clone(),否則就直接使用我們的clone()(現(xiàn)在已成為public),而那并不一定是我們所希望的(然而,由于Object.clone()已制作了實際對象的一個副本,所以也有可能允許這種情況)。protected的技巧在這里只能用一次:首次從一個不具備克隆能力的類繼承,而且想使一個類變成“能夠克隆”。而在從我們的類繼承的任何場合,clone()方法都是可以使用的,因為Java不可能在衍生之后反而縮小方法的訪問范圍。換言之,一旦對象變得可以克隆,從它衍生的任何東西都是能夠克隆的,除非使用特殊的機制(后面討論)令其“關(guān)閉”克隆能力。<br>
<br>
2. 實現(xiàn)Cloneable接口<br>
為使一個對象的克隆能力功成圓滿,還需要做另一件事情:實現(xiàn)Cloneable接口。這個接口使人稍覺奇怪,因為它是空的!<br>
interface Cloneable {}<br>
之所以要實現(xiàn)這個空接口,顯然不是因為我們準備上溯造型成一個Cloneable,以及調(diào)用它的某個方法。有些人認為在這里使用接口屬于一種“欺騙”行為,因為它使用的特性打的是別的主意,而非原來的意思。Cloneable 
interface的實現(xiàn)扮演了一個標記的角色,封裝到類的類型中。<br>
兩方面的原因促成了Cloneable interface的存在。首先,可能有一個上溯造型句柄指向一個基礎(chǔ)類型,而且不知道它是否真的能克隆那個對象。在這種情況下,可用instanceof關(guān)鍵字(第11章有介紹)調(diào)查句柄是否確實同一個能克隆的對象連接:<br>

?? 快捷鍵說明

復(fù)制代碼 Ctrl + C
搜索代碼 Ctrl + F
全屏模式 F11
切換主題 Ctrl + Shift + D
顯示快捷鍵 ?
增大字號 Ctrl + =
減小字號 Ctrl + -
亚洲欧美第一页_禁久久精品乱码_粉嫩av一区二区三区免费野_久草精品视频
91麻豆国产香蕉久久精品| 91免费观看视频在线| 国产.欧美.日韩| 91福利社在线观看| 久久亚洲一级片| 亚欧色一区w666天堂| 不卡在线视频中文字幕| 日韩美女一区二区三区| 一区二区在线免费观看| 国产河南妇女毛片精品久久久| 7777精品伊人久久久大香线蕉超级流畅 | 国产成人精品www牛牛影视| 欧美四级电影在线观看| 国产精品美女久久久久久久网站| 天涯成人国产亚洲精品一区av| 成人av在线观| 久久综合久久鬼色| 免费欧美在线视频| 欧美日韩1234| 亚洲一区二区三区国产| eeuss鲁片一区二区三区在线看| 欧美v亚洲v综合ⅴ国产v| 午夜精品在线看| 91国偷自产一区二区使用方法| 中文字幕中文字幕一区二区| 国产成人在线视频网站| 久久婷婷一区二区三区| 蜜臀91精品一区二区三区| 欧美女孩性生活视频| 亚洲成人手机在线| 色妹子一区二区| 一区二区三区四区乱视频| 色国产精品一区在线观看| 亚洲欧洲99久久| 99精品热视频| 亚洲精品一二三四区| 91视频免费看| 亚洲免费三区一区二区| 91免费看片在线观看| 亚洲视频在线一区| 91极品美女在线| 亚洲午夜羞羞片| 欧美精品v日韩精品v韩国精品v| 亚洲国产精品一区二区www| 欧美日韩在线播放三区| 婷婷开心激情综合| 日韩欧美中文一区| 国产麻豆视频精品| 国产精品欧美精品| 欧洲精品中文字幕| 久久国产福利国产秒拍| 久久九九久久九九| 成人免费视频视频在线观看免费| 最新国产成人在线观看| 欧美三级日本三级少妇99| 五月综合激情网| 欧美成人a∨高清免费观看| 国产精品99久久久久久有的能看| 亚洲国产岛国毛片在线| 91成人在线观看喷潮| 美国十次综合导航| 国产欧美精品一区| 欧美视频中文一区二区三区在线观看 | 人人狠狠综合久久亚洲| 亚洲精品一区二区三区福利| 成人黄动漫网站免费app| 国产精品高清亚洲| 91精品国产综合久久精品app | 欧美顶级少妇做爰| 国产一区二区三区四区五区入口| 亚洲欧洲精品成人久久奇米网 | 成人黄色av网站在线| 亚洲成a人片综合在线| 久久综合色综合88| 色吧成人激情小说| 国模娜娜一区二区三区| 亚洲靠逼com| 精品乱人伦小说| 91国产福利在线| 国产成人精品免费在线| 视频一区中文字幕国产| 中文无字幕一区二区三区| 欧美久久一区二区| 97久久精品人人做人人爽| 美女国产一区二区三区| 一区二区三区成人| 久久久一区二区| 欧美一区二区视频在线观看| av高清久久久| 国产在线一区观看| 亚洲国产日产av| 夜夜揉揉日日人人青青一国产精品| 久久午夜色播影院免费高清| 欧美伊人久久久久久久久影院| 国产成人综合在线观看| 秋霞成人午夜伦在线观看| 夜色激情一区二区| 国产精品三级av| 久久这里只精品最新地址| 337p亚洲精品色噜噜狠狠| 色婷婷综合五月| 91网址在线看| 成人动漫av在线| 国产精品一区二区你懂的| 老司机免费视频一区二区| 亚洲国产成人av| 亚洲在线成人精品| 亚洲视频一区二区在线观看| 欧美激情在线看| 久久男人中文字幕资源站| 日韩欧美一级在线播放| 欧美一区二区视频观看视频| 欧美视频中文字幕| 欧美在线视频全部完| 91国产免费看| 欧美亚洲一区三区| 色哟哟一区二区| 色综合久久久久久久| 色综合天天综合在线视频| 97se狠狠狠综合亚洲狠狠| 成人自拍视频在线观看| 国产风韵犹存在线视精品| 国产成人精品一区二区三区网站观看| 老司机精品视频在线| 另类小说图片综合网| 久久国产精品99久久人人澡| 蜜桃久久精品一区二区| 国模一区二区三区白浆| 色久优优欧美色久优优| 在线观看亚洲专区| 欧美日韩成人高清| 欧美一区二区三区免费观看视频 | 欧美一级黄色录像| 亚洲精品一区二区三区影院| 久久精品免视看| 成人欧美一区二区三区小说 | 精品国一区二区三区| 国产亚洲短视频| 亚洲天堂久久久久久久| 亚洲丰满少妇videoshd| 奇米精品一区二区三区在线观看| 美腿丝袜亚洲综合| 成人深夜视频在线观看| 欧美日韩一区在线| 日韩欧美中文一区二区| 中文字幕第一区二区| 亚洲精品一二三四区| 日韩和欧美一区二区三区| 国产高清不卡一区| 91国偷自产一区二区三区成为亚洲经典 | 国产综合色产在线精品| 成av人片一区二区| 欧美一区二区三区人| 国产精品久久久久三级| 亚洲va韩国va欧美va| 国产成人欧美日韩在线电影| 91黄色免费看| 国产网站一区二区| 亚洲3atv精品一区二区三区| 国产麻豆成人精品| 日本高清不卡一区| 久久一区二区三区四区| 亚洲高清免费视频| 成人黄色免费短视频| 91精品国产麻豆| 综合久久久久久久| 久久99蜜桃精品| 欧美亚洲国产怡红院影院| 亚洲欧美在线另类| 狠狠色狠狠色综合日日91app| 91黄视频在线| 国产精品进线69影院| 国内久久精品视频| 欧美三级电影在线看| 国产精品伦理一区二区| 免费在线视频一区| 在线观看三级视频欧美| 日本一区二区电影| 精品一区二区综合| 91麻豆精品国产91久久久久| 亚洲精品中文在线影院| 成人动漫在线一区| 久久久91精品国产一区二区三区| 日韩在线一二三区| 欧美日韩视频在线观看一区二区三区| 中文字幕不卡在线观看| 国产毛片精品一区| 精品美女在线播放| 蜜桃av一区二区三区电影| 欧美精品日韩一本| 亚洲一区二区三区四区的| 99热这里都是精品| 国产精品久久久久久久久免费丝袜 | 久久av中文字幕片| 日韩免费看网站| 奇米影视7777精品一区二区| 91精品国产入口| 日本中文字幕一区二区有限公司| 在线电影院国产精品| 天天免费综合色|