下載本文檔
版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)
文檔簡(jiǎn)介
1、Java對(duì)象及其引用關(guān)鍵字: java對(duì)象引用 Java對(duì)象及其引用 關(guān)于對(duì)象與引用之間的一些基本概念。 初學(xué)Java時(shí),在很長(zhǎng)一段時(shí)間里,總覺得基本概念很模糊。后來才知道,在許多Java書中,把對(duì)象和對(duì)象的引用混為一談??墒?,如果我分不清對(duì)象與對(duì)象引用, 那實(shí)在沒法很好地理解下面的面向?qū)ο蠹夹g(shù)。把自己的一點(diǎn)認(rèn)識(shí)寫下來,或許能讓初學(xué)Java的朋友們少走一點(diǎn)彎路。 為便于說明,我們先定義一個(gè)簡(jiǎn)單的類:class Vehicle int passengers; int fuelcap; int mpg; 有了這個(gè)模板,就可以用它來創(chuàng)建對(duì)象: Vehicle veh1 = new Vehicle()
2、; 通常把這條語句的動(dòng)作稱之為創(chuàng)建一個(gè)對(duì)象,其實(shí),它包含了四個(gè)動(dòng)作。 1)右邊的“new Vehicle”,是以Vehicle類為模板,在堆空間里創(chuàng)建一個(gè)Vehicle類對(duì)象(也簡(jiǎn)稱為Vehicle對(duì)象)。 2)末尾的()意味著,在對(duì)象創(chuàng)建后,立即調(diào)用Vehicle類的構(gòu)造函數(shù),對(duì)剛生成的對(duì)象進(jìn)行初始化。構(gòu)造函數(shù)是肯定有的。如果你沒寫,Java會(huì)給你補(bǔ)上一個(gè)默認(rèn)的構(gòu)造函數(shù)。3)左邊的“Vehicle veh1”創(chuàng)建了一個(gè)Vehicle類引用變量。所謂Vehicle類引用,就是以后可以用來指向Vehicle對(duì)象的對(duì)象引用。 4)“=”操作符使對(duì)象引用指向剛創(chuàng)建的那個(gè)Vehicle對(duì)象。 我們可以
3、把這條語句拆成兩部分:Vehicle veh1; veh1 = new Vehicle(); 效果是一樣的。這樣寫,就比較清楚了,有兩個(gè)實(shí)體:一是對(duì)象引用變量,一是對(duì)象本身。 在堆空間里創(chuàng)建的實(shí)體,與在數(shù)據(jù)段以及棧空間里創(chuàng)建的實(shí)體不同。盡管它們也是確確實(shí)實(shí)存在的實(shí)體,但是,我們看不見,也摸不著。不僅如此,我們仔細(xì)研究一下第二句,找找剛創(chuàng)建的對(duì)象叫什么名字?有人說,它叫“Vehicle”。不對(duì),“Vehicle”是類(對(duì)象的創(chuàng)建模板)的名字。 一個(gè)Vehicle類可以據(jù)此創(chuàng)建出無數(shù)個(gè)對(duì)象,這些對(duì)象不可能全叫“Vehicle”。 對(duì)象連名都沒有,沒法直接訪問它。我們只能通過對(duì)象引用來間接訪問對(duì)象。
4、 為了形象地說明對(duì)象、引用及它們之間的關(guān)系,可以做一個(gè)或許不很妥當(dāng)?shù)谋扔鳌?duì)象好比是一只很大的氣球,大到我們抓不住它。引用變量是一根繩, 可以用來系汽球。 如果只執(zhí)行了第一條語句,還沒執(zhí)行第二條,此時(shí)創(chuàng)建的引用變量veh1還沒指向任何一個(gè)對(duì)象,它的值是null。引用變量可以指向某個(gè)對(duì)象,或者為null。 它是一根繩,一根還沒有系上任何一個(gè)汽球的繩。執(zhí)行了第二句后,一只新汽球做出來了,并被系在veh1這根繩上。我們抓住這根繩,就等于抓住了那只汽球。 再來一句:Vehicle veh2;就又做了一根繩,還沒系上汽球。如果再加一句: veh2 = veh1; 系上了。這里,發(fā)生了復(fù)制行為。但是,要說
5、明的是,對(duì)象本身并沒有被復(fù)制,被復(fù)制的只是對(duì)象引用。結(jié)果是,veh2也指向了veh1所指向的對(duì)象。兩根繩系的是同一只汽球。 如果用下句再創(chuàng)建一個(gè)對(duì)象: veh2 = new Vehicle();則引用變量veh2改指向第二個(gè)對(duì)象。從以上敘述再推演下去,我們可以獲得以下結(jié)論:(1)一個(gè)對(duì)象引用可以指向0個(gè)或1個(gè)對(duì)象(一根繩子可以不系汽球,也可以系一個(gè)汽球); (2)一個(gè)對(duì)象可以有N個(gè)引用指向它(可以有N條繩子系住一個(gè)汽球)。 如果再來下面語句: veh1 = veh2; 按上面的推斷,veh1也指向了第二個(gè)對(duì)象。這個(gè)沒問題。問題是第一個(gè)對(duì)象呢?沒有一條繩子系住它,它飛了。多數(shù)書里說,它被Java
6、的垃圾回收機(jī)制回收了。 這不確切。正確地說,它已成為垃圾回收機(jī)制的處理對(duì)象。至于什么時(shí)候真正被回收,那要看垃圾回收機(jī)制的心情了。 由此看來,下面的語句應(yīng)該不合法吧?至少是沒用的new Vehicle(); 不對(duì)。它是合法的,而且可用的。譬如,如果我們僅僅為了打印而生成一個(gè)對(duì)象,就不需要用引用變量來系住它。最常見的就是打印字符串:System.out.println(“I am Java!”); 字符串對(duì)象“I am Java!”在打印后即被丟棄。有人把這種對(duì)象稱之為臨時(shí)對(duì)象。對(duì)象與引用的關(guān)系將持續(xù)到對(duì)象回收。 Java對(duì)象及引用 Java對(duì)象及引用是容易混淆卻又必須掌握的基礎(chǔ)知識(shí),本章闡述Ja
7、va對(duì)象和引用的概念,以及與其密切相關(guān)的參數(shù)傳遞。 先看下面的程序:StringBuffer s; s = new StringBuffer(Hello World!); 第一個(gè)語句僅為引用(reference)分配了空間,而第二個(gè)語句則通過調(diào)用類(StringBuffer)的構(gòu)造函數(shù)StringBuffer(String str)為類生成了一個(gè)實(shí)例(或稱為對(duì)象)。這兩個(gè)操作被完成后,對(duì)象的內(nèi)容則可通過s進(jìn)行訪問在Java里都是通過引用來操縱對(duì)象的。 Java對(duì)象和引用的關(guān)系可以說是互相關(guān)聯(lián),卻又彼此獨(dú)立。彼此獨(dú)立主要表現(xiàn)在:引用是可以改變的,它可以指向別的對(duì)象,譬如上面的s,你可以給它另外的
8、對(duì)象,如:s = new StringBuffer(Java); 這樣一來,s就和它指向的第一個(gè)對(duì)象脫離關(guān)系。從存儲(chǔ)空間上來說,對(duì)象和引用也是獨(dú)立的,它們存儲(chǔ)在不同的地方,對(duì)象一般存儲(chǔ)在堆中,而引用存儲(chǔ)在速度更快的堆棧中。 引用可以指向不同的對(duì)象,對(duì)象也可以被多個(gè)引用操縱,如:StringBuffer s1 = s; 這條語句使得s1和s指向同一個(gè)對(duì)象。既然兩個(gè)引用指向同一個(gè)對(duì)象,那么不管使用哪個(gè)引用操縱對(duì)象,對(duì)象的內(nèi)容都發(fā)生改變,并且只有一份,通過s1和s得到的內(nèi)容自然也一樣,(String除外,因?yàn)镾tring始終不變,String s1=”AAAA”; String s=s1,操作s,s
9、1由于始終不變,所以為s另外開辟了空間來存儲(chǔ)s,)如下面的程序: StringBuffer s; s = new StringBuffer(Java); StringBuffer s1 = s; s1.append( World); System.out.println(s1= + s1.toString();/打印結(jié)果為:s1=Java World System.out.println(s= + s.toString();/打印結(jié)果為:s=Java World 上面的程序表明,s1和s打印出來的內(nèi)容是一樣的,這樣的結(jié)果看起來讓人非常疑惑,但是仔細(xì)想想,s1和s只是兩個(gè)引用,它們只是操縱桿而已
10、,它們指向同一個(gè)對(duì)象,操縱的也是同一個(gè)對(duì)象,通過它們得到的是同一個(gè)對(duì)象的內(nèi)容。這就像汽車的剎車和油門,它們操縱的都是車速,假如汽車開始的速度是80,然后你踩了一次油門,汽車加速了,假如車速升到了120,然后你踩一下剎車,此時(shí)車速是從120開始下降的,假如下降到60,再踩一次油門,車速則從60開始上升,而不是從第一次踩油門后的120開始。也就是說車速同時(shí)受油門和剎車影響,它們的影響是累積起來的,而不是各自獨(dú)立(除非剎車和油門不在一輛車上)。所以,在上面的程序中,不管使用s1還是s操縱對(duì)象,它們對(duì)對(duì)象的影響也是累積起來的(更多的引用同理)。 只有理解了對(duì)象和引用的關(guān)系,才能理解參數(shù)傳遞。 一般面試
11、題中都會(huì)考Java傳參的問題,并且它的標(biāo)準(zhǔn)答案是Java只有一種參數(shù)傳遞方式:那就是按值傳遞,即Java中傳遞任何東西都是傳值。如果傳入方法的是基本類型的東西,你就得到此基本類型的一份拷貝。如果是傳遞引用,就得到引用的拷貝。 一般來說,對(duì)于基本類型的傳遞,我們很容易理解,而對(duì)于對(duì)象,總讓人感覺是按引用傳遞,看下面的程序:public class ObjectRef /基本類型的參數(shù)傳遞 public static void testBasicType(int m) System.out.println(m= + m);/m=50 m = 100; System.out.println(m= +
12、 m);/m=100 /參數(shù)為對(duì)象,不改變引用的值 ? public static void add(StringBuffer s) s.append(_add); /參數(shù)為對(duì)象,改變引用的值 ? public static void changeRef(StringBuffer s) s = new StringBuffer(Java); public static void main(String args) int i = 50; testBasicType(i); System.out.println(i);/i=50 StringBuffer sMain = new StringBu
13、ffer(init); System.out.println(sMain= + sMain.toString();/sMain=init add(sMain); System.out.println(sMain= + sMain.toString();/sMain=init_add changeRef(sMain); System.out.println(sMain= + sMain.toString();/sMain=init_add 以上程序的允許結(jié)果顯示出,testBasicType方法的參數(shù)是基本類型,盡管參數(shù)m的值發(fā)生改變,但并不影響i。 add方法的參數(shù)是一個(gè)對(duì)象,當(dāng)把sMain傳
14、給參數(shù)s時(shí),s得到的是sMain的拷貝,所以s和sMain指向同一個(gè)對(duì)象,因此,使用s操作影響的其實(shí)就是sMain指向的對(duì)象,故調(diào)用add方法后,sMain指向的對(duì)象的內(nèi)容發(fā)生了改變。 在changeRef方法中,參數(shù)也是對(duì)象,當(dāng)把sMain傳給參數(shù)s時(shí),s得到的是sMain的拷貝,但與add方法不同的是,在方法體內(nèi)改變了s指向的對(duì)象(也就是s指向了別的對(duì)象,牽著氣球的繩子換氣球了),給s重新賦值后,s與sMain已經(jīng)毫無關(guān)聯(lián),它和sMain指向了不同的對(duì)象,所以不管對(duì)s做什么操作,都不會(huì)影響sMain指向的對(duì)象,故調(diào)用changeRef方法前后sMain指向的對(duì)象內(nèi)容并未發(fā)生改變。 對(duì)于ad
15、d方法的調(diào)用結(jié)果,可能很多人會(huì)有這種感覺:這不明明是按引用傳遞嗎?對(duì)于這種問題,還是套用Bruce Eckel的話:這依賴于你如何看待引用,最終你會(huì)明白,這個(gè)爭(zhēng)論并沒那么重要。真正重要的是,你要理解,傳引用使得(調(diào)用者的)對(duì)象的修改變得不可預(yù)期。 public class Test public int I,j; public void test_m(Test a) Test b=new Test(); b.i=1; b.j=2; a=b; public void test_m1(Test a ) a.i = 1; a.j =2; public static void main(String argv) Test t=new Test(); t.i=5; t.j=6; System.out.println( t.i=+ t.
溫馨提示
- 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
- 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 人人文庫網(wǎng)僅提供信息存儲(chǔ)空間,僅對(duì)用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對(duì)用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對(duì)任何下載內(nèi)容負(fù)責(zé)。
- 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請(qǐng)與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對(duì)自己和他人造成任何形式的傷害或損失。
最新文檔
- 二零二五年度房地產(chǎn)展示展覽項(xiàng)目投資合作合同3篇
- 幼兒園安全培訓(xùn)主題
- 2025年度租賃合同標(biāo)的詳細(xì)描述與合同屬性分析2篇
- 2024版二手房買賣合同直接買賣
- 2024某企業(yè)與物流公司的委托運(yùn)輸合同
- 二零二五年度鍋爐供暖設(shè)備承包與安全保養(yǎng)服務(wù)協(xié)議3篇
- 2024軟件開發(fā)與系統(tǒng)集成服務(wù)合同
- 專業(yè)土方運(yùn)輸服務(wù)協(xié)議范本2024版B版
- 遼寧省營(yíng)口市(2024年-2025年小學(xué)六年級(jí)語文)部編版小升初模擬(下學(xué)期)試卷及答案
- 專項(xiàng)包車服務(wù)合作合同(2024年度版)版B版
- 無人駕駛 物流行業(yè)市場(chǎng)調(diào)研分析報(bào)告
- 電力工程施工人員培訓(xùn)方案
- 3-U9C操作培訓(xùn)-MRP基礎(chǔ)
- 8年級(jí)上冊(cè)(人教版)物理電子教材-初中8~9年級(jí)物理電子課本
- 2024至2030年中國(guó)銅制裝飾材料行業(yè)投資前景及策略咨詢研究報(bào)告
- 中金公司在線測(cè)評(píng)真題
- 項(xiàng)目資金管理統(tǒng)籌實(shí)施方案
- 2024供應(yīng)商大會(huì)策劃方案
- 政治-經(jīng)濟(jì)與社會(huì) 教材探究與分享參考答案高中政治統(tǒng)編版必修二
- 湖南省常德市桃源縣市級(jí)名校2024年中考數(shù)學(xué)模試卷含解析
- 2024小學(xué)語文六年級(jí)上冊(cè)第四單元:大單元整體教學(xué)課件
評(píng)論
0/150
提交評(píng)論